2011-05-12 34 views
1

申し訳ありませんが、私はtutorialsを読んで、私の頭をあまりにもぼやけて今はっきりと見ることができません。Regex - 繰り返しグループをキャプチャする

私は、関数シグネチャからパラメータと型情報を取得しようとしています。したがって、このようなシグネチャ与えられた:

function(/*string*/a,b,c) 

私はこのような部品を取得したい:

type: string 
param:a 
param:b 
param:c 

をこれもOKです:

type: string 
param:a 
type: null (or whitespace) 
param:b 
type: null (or whitespace) 
param:c 

だから私はこの正規表現これを思い付きましたキャプチャを繰り返すという間違いを繰り返しています(明示的なキャプチャをオンにしました)。

function\(((\/\*(?<type>[a-zA-Z]+)\*\/)?(?<param>[0-9a-zA-Z_$]+),?)*\) 

問題は、私は間違いを訂正できません。 。。!:(、一致/全機能を検証
まず、あなたはすべてのデータを取得するために2つのステップを必要とするだろう一般

+0

あなたはどの言語を使用していますか?これが.Netパターンなら、あなたは運がいいです。それ以外の場合は、おそらく単一のステップでは不可能です。 – Kobi

+0

私は.Netを使わなくてもそれを解決したいと考えていましたが、ええ、私は結局.Netを使用しています。また、Capturesコレクションを見てきましたが、キャプチャをグループに関連付ける信頼性の高い方法はありません(または何かを見落としていますか?)。 – Mrchief

+0

投稿された回答を参照してください。 'Match.Captures'は簡単に見つけられますが、あまり役に立ちません。通常は' Group.Captures'が必要です(私はもちろんこれを推測しています)。 – Kobi

答えて

3

を助けてください:今、あなたが持つparameters基を有していても

function\((?<parameters>((\/\*[a-zA-Z]+\*\/)?[0-9a-zA-Z_$]+,?)*)\) 

注意すべてのパラメータ。パターンの一部を再度一致させて、パラメータの一致をすべて取得することもできます。この場合は、,で分割します。

.Netを使用している場合は、 Netは各グループのすべてのキャプチャを完全に記録しているので、コレクションを使用することができます:

match.Groups["param"].Captures 

いくつかの注意:あなたは複数のタイプをキャプチャしたい場合は

  • 、あなたは間違いなくあなたが並べ替えることができますが、あなたが簡単に(試合を組み合わせることができますので、空のマッチをしたいが、1対1のキャプチャはそれほど役に立ちません)。その場合には、オプションのグループに内部キャプチャしたグループたい:(?<type>(\/\*[a-zA-Z]+\*\/)?)
  • をあなたはネットのパターンでスラッシュをエスケープする必要はありません - /がそこには特別な意味(C#の/を持っていないネットが正規表現の区切り文字を持っていません。 )。

キャプチャの使用例を次に示します。再び、主なポイントは、typeparamの間の関係を維持することです:空のタイプを捕捉したいので、カウントを失うことはありません。
パターン:

function 
\(
(?: 
    (?: 
     /\*(?<type>[a-zA-Z]+)\*/ # type within /* */ 
     |       # or 
     (?<type>)     # capture an empty type. 
    ) 
    (?<param> 
     [0-9a-zA-Z_$]+ 
    ) 
    (?:,|(?=\s*\)))  # mandatory comma, unless before the last ')' 
)* 
\) 

コード:

Match match = Regex.Match(s, pattern, RegexOptions.IgnorePatternWhitespace); 
CaptureCollection types = match.Groups["type"].Captures; 
CaptureCollection parameters = match.Groups["param"].Captures; 
for (int i = 0; i < parameters.Count; i++) 
{ 
    string parameter = parameters[i].Value; 
    string type = types[i].Value; 
    if (String.IsNullOrEmpty(type)) 
     type = "NO TYPE"; 
    Console.WriteLine("Parameter: {0}, Type: {1}", parameter, type); 
} 
+0

もう一度確認しました。複数のタイプを取得します。別の考え方は、括弧の間に文字列全体をキャプチャし、コンマで区切ってからループを取り、タイプとパラメータを1つずつキャプチャすることです。 – Mrchief

+0

@Murchief - 右、私の悪い!私は答えを更新しました。あなたが提案している別のアイデアは、間違いなく名前のために私が提案したものでもあります。私もそれを修正しました。 – Kobi

+0

何とか私はここに私のコメントを失った!わかりました。私はあなたの最初のメモで先に分かれていて、あなたが示したものと同じ "代替"の解決策を理解していませんでした。私はGroup.Capturesも試しましたが、それはちょっと面倒です。以前のすべてのキャプチャを指示しますが、それはフラットな方法で行います。パラメタとタイプを関連付けることができるようにする必要があります。フラットなランニングリストを持たないのはあまり役に立ちません。スラッシュは私にとって新しいものでした。 – Mrchief

1

あなたはその後、自身のグループ内で繰り返しキャプチャを囲む、非捕捉に?:を使用して言及した参照されるページ。私は彼らがこのようなことを示唆していると推測していますfunction\(((?:(\/\*(?<type>[a-zA-Z]+)\*\/)?(?<param>[0-9a-zA-Z_$]+),?)*)\)

http://gskinner.com/RegExr/私の表現をテストするのが好きですが、繰り返しのキャプチャは表示されません。他の非.NET言語の値を見るために戻った戻り構造体で結果をループする必要があります。

申し訳ありませんが、私はこの質問がアクティブであったので、それはしばらくしている...もっとthuroughly

+1

http://regexstorm.net/testerは.Netの正規表現をテストするのに便利なサイトです。 http://regexhero.net/tester/もありますが、それはシルバーライトベースであり、お金のために時折あなたを怒らせます。 – Kobi

+0

regexheroはお金のためだけでなく、ブラウザをダウンさせることがあります(長期間使用するとSilverlightプラグインがクラッシュします)。 Regexstormは有望そうです。どうも! – Mrchief

+0

@Murchief - どのブラウザ/ OSをお使いですか?私はRegex Heroがブラウザをクラッシュさせることは見ていない。 –

1

をテストすることができませんでしたが、私はようやく答えを見つけたと思います。

私はあなたと同じ状況を探していたと思いますが、PHPで使用するために、PCREの\K\Gコマンドを使って、実際にうまく動作していることがわかった別の投稿に答えがあります。 PHP Regular Expression - Repeating Match of a Group

私の問題は、各行に6桁の数字、20桁の1桁または2桁の数字、関連のない1桁または2桁の数字が含まれているテーブルのすべてのセルの値を取り出そうとしていました。数。解決策は次のとおりです。

<tr class="[^"]*">\s+<td>(\d{6})<\/td>|\G<\/td>[^<>]*+<td>\K\d{1,6}|<td>(\d{1,2})<\/td> 

私は自分自身と言うと非常に素晴らしい解決策です!

+1

問題はそれぞれの技術は、そのようなことを処理する独自のニッチな方法を持っています。セットや正規表現の中に何かがあったら幸いです。だから今は誰か.NetやPCREを使用していない場合、彼らは冷たい水の中に放置されています。 – Mrchief

関連する問題