2011-08-02 7 views
4

私は解析する問題が発生しました。これは、動作するパターンが再帰的でなければならないという点を除けば、かなり小さい正規表現で解決します。
例:.NET用の代替正規表現エンジン、再帰をサポート

{([^{}]*(?:{(?1)})?) 

私はそれを一致させたいどのような、特定のRTFヘッダーですが、それを行うには、私はそれが再帰的にする必要があります。

{\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fnil\fcharset0 Tahoma;}} 

パターンのこれらの種類(多分別の構文)に一致するものを見つけることができるようになる.NETの非真の正規表現のようなエンジンの実装のいくつかの種類がありますか?

更新:

私は本当に私を助けている、以下のコメントとして非常に包括的なリンクを提供している正規表現の.NET実装、特にQtax、中Balancing Groupオプションについての私を知らせるために皆に感謝しますこれについては何であるかを理解し、具体的な例に答えを投稿することもできます。あなたがこれを読んでいて、それがあなたを助けてくれたなら、その答えをアップアップしてください。
しかし... .NET Regexのようなエンジンで再帰可能性に関する一般的な質問には答えられませんでした。この例は、幸いにも(私は挑戦が好きです)私が会った唯一のものではありません。そして、この解決策を使用して他の状況を解決することはできませんが、一致を参照するのではなく、パターンのシーケンスを再帰が可能な点に再利用することによってのみ解決できます。

+2

://を あなたはまた、最後に}忘れてしまったとの文字列、使用をマッチさせたい場合blogs.msdn.com/b/bclteam/archive/2005/03/15/396452.aspx)がこの問題に役立つ可能性があります。 – vcsjones

+1

マニュアルのバランシンググループhttp://msdn.microsoft.com/en-us/library/bs2twtah.aspx#balancing_group_definition – Qtax

+0

はい、私は非常に有益でした、ありがとうございました。しかし、再帰的な正規表現が必要なのはそれだけではありません。 – AlexanderMP

答えて

3

たとえば、balancing groupを使用すると効果があります。

次のような表現を使用することができます。

{ 
[^{}]* 
(?:({)[^{}]*)* 
(?'-1'})* 
(?(1)(?!)) 
} 

例:

string re = @"{[^{}]*(?:({)[^{}]*)*(?'-1'})*(?(1)(?!))}"; 
string str = "foo {bar} baz {foo{bar{baz}}} {f{o{o}}{bar}baz} {foo{bar}baz}"; 

Console.WriteLine("Input: \"{0}\"", str); 
foreach (Match m in Regex.Matches(str, re)) 
{ 
    Console.WriteLine("Match: \"{0}\"", m); 
} 

出力:でもQtaxのexempleは非常に良いと明確である

Input: "foo {bar} baz {foo{bar{baz}}} {f{o{o}}{bar}baz} {foo{bar}baz}" 
Match: "{bar}" 
Match: "{foo{bar{baz}}}" 
Match: "{o{o}}" 
Match: "{bar}" 
Match: "{bar}" 
+0

この特定の質問に対する完全な答えではありませんが、最も近いものです。ありがとうございました。 – AlexanderMP

3

、それが一致しませんでした完全に私にとっては{f{o{o}}{bar}baz}の代わりに{o{o}}を返すからです。

時間を探した後、私の解決策は、(ほぼ同じ例を使用して)されています

入力:

string re = @"{(((?<Counter>{)*[^{}]*)*((?<-Counter>})*[^{}]*)*)*(?(Counter)(?!))}"; 
string str = "foo {bar} baz {foo{bar{{baz}a{a{b}}}}} {f{o{o}}{bar{a{b{c}}{d}}}baz} {foo{bar}baz}"; 

Console.WriteLine("Input: \"{0}\"", str); 
foreach (Match m in Regex.Matches(str, re)) 
{ 
    Console.WriteLine("Match: \"{0}\"", m); 
} 

出力:

Input: "foo {bar} baz {foo{bar{{baz}a{a{b}}}}} {f{o{o}}{bar{a{b{c}}{d}}}baz} {foo{bar}baz}" 
Match: "{bar}" 
Match: "{foo{bar{{baz}a{a{b}}}}}" 
Match: "{f{o{o}}{bar{a{b{c}}{d}}}baz}" 
Match: "{foo{bar}baz}" 

いくつかの説明、私はカウンタをインクリメントそれぞれ{の場合は、それぞれ}でカウンタを減らします。最後に正規表現はカウンタが空の場合にのみ一致します((?(Counter)(?!)))。

深い再帰と代替ブラケットではうまくいくようです。

このsiteを参照すると、この正規表現の作成にも役立ちます。

こちらがお役に立てば幸いです。

PS:再帰への直接の答えではありませんが、[バランス木](HTTP用の.NETのサポート

string re = @"{(((?<Counter>{)*[^{}]*)*((?<-Counter>(}|$))*[^{}]*)*)*(?(Counter)(?!))(}|$)"; 
string str = "foo {bar} baz {foo{bar{{baz}a{a{b}}}}} {f{o{o}}{bar{a{b{c}}{d}}}baz} {foo{bar}b{az"; 
関連する問題