2012-04-25 15 views
1

を使用して、文字列内のグループをキャプチャすることはできません:は、私は、次の形式の文字列に一致するようにしようとしているREGEX

"に続いて正確に一つの資本ラテンアルファベットの記号がある最も左側に、ある
S->A 
S->AbCd 
S->A|b|C|d 
S->Ab|B|cde|dB 

- > 'リテラル。その後、リテラルは、正確に1つの大文字/小文字のラテンアルファベット記号、または「|」記号で区切られたそのような記号のグループに続くことができるそのような記号の連結に従います。シンボル。
また、文字列全体がこの形式に準拠しているかどうかを確認するだけでなく、左端の大文字記号とすべての記号グループを ' - >'リテラルの後ろに取り込むことができるようにしたいと思います。これまでのところ私はこの正規表現が出ている:

([A-Z]{1})->([a-zA-Z]+)(?:(?:\|)([a-zA-Z]+))* 

私はに対してそれをテストする場合、例えば、この文字列:

S->Ab|B|c|d 

私は以下の結果を(テストはRegexBuddyで行う)を取得します

Match 1: S->Ab|B|c|d 
Group 1: S 
Group 2: Ab 
Group 3: d 

良いことは、正規表現が文字列全体と一致することです(これは正しい)。しかし問題は明らかです:私の正規表現は最初と最後のシンボルグループだけを ' - >'リテラルの後に取り込みます。どうして?正規表現の私の理解に基づいて表現

(?:(?:\|)([a-zA-Z]+))* 

のこの部分は、ALL区切り記号群と一致する必要があります。私はそれが記事'Repeating a Capturing Group vs. Capturing a Repeated Group'に記載されているものに関連するものだと信じています。私は私の正規表現を少しでも試してみましたが、まだ満足のいく結果は得られませんでした。助言がありますか?

+3

正規表現? –

+0

左端が大文字のラテン文字でなければならない場合は、[a-z]部分を削除する必要があります。 –

答えて

1

はい、問題は、キャプチャグループを繰り返していることです。

(?:(?:\|)([a-zA-Z]+))* 
     ^^^^^^^^^^^ 
      third group 

あなたは正しいです、この全体の一部には、お使いの繰り返しグループのすべてを一致され、すべてのマッチングが行われた後、結果として、あなただけのこのグループの最後の試合を見ることができるので、それらの試合のそれぞれは、$3に保存されていますあなたの例ではdです。

次に、あなたの結果はキャプチャグループにこの

Match 1: S->Ab|B|c|d 
Group 1: S 
Group 2: Ab 
Group 3: |B|c|d 
+0

あなたのヒントをありがとう。 しかし、正規表現を書いて、 '|'で始まるすべての一致する項目に対して別のグループを生成する方法がないことを正しく理解していますか? – davidgale

+0

あなたはどの言語を使用していますか?ほとんどはそうではありませんが、私はそれができると思います(そして私はPerl 6を聞いたことがあります)。 – stema

1

(?:...)は、非キャプチャグループを意味します。

のキャプチャグループを使用する場合は、代わりに(...)を使用してください。あなたは各要素を個別にしたい場合は、区切り文字で分割することができます

([a-zA-Z]{1})->([a-zA-Z]+)(\|[a-zA-Z]+)* 

はこれを試してみてください。

2

正規表現にはキャプチャ括弧が3つしかないので、3つのグループを取り出すことができます(「繰り返しグループのキャプチャとキャプチャグループの繰り返し」に関連しています)。グループの数は常に固定です。わかりやすくするために、物事を分割するためのPerlのような間隔m//xを使用して

:3つの捕獲する部分が示され

([a-zA-Z]{1}) -> ([a-zA-Z]+) (?: (?:\|) ([a-zA-Z]+))* 
^-----------^  ^---------^    ^---------^ 

。他のカッコは非キャプチャです。

([a-zA-Z]{1}) -> ([a-zA-Z]+) ((?:\|) (?:[a-zA-Z]+))* 

をしかし、あなたは、サブフィールドを取得するには、おそらくsplit操作で、末尾のグループ形式の後処理する必要があります。もちろん、あなたは末尾のグループの全体をキャプチャすることができます。

1

のように3試合全てのシンボル([a-zA-Z]+)を見えるこの

([a-zA-Z]{1})->([a-zA-Z]+)((?:(?:\|)[a-zA-Z]+)*) 

のようなあなたの繰り返しグループを取り込むことができます - それは最初の「B」にマッチします、正規表現が次の文字の後に続くときに "c"に置き換えられます。結果は次のように "d"に置き換えられます。

関連する問題