2016-12-27 4 views
2

をキャプチャしていない、私は文字列が含まれているスニペット「言語」の種類をキャプチャするために苦労しています:メイク正規表現は、だから、ORキャプチャグループ

File (En,Fr,De,Es,It).doc <== should match all 5 languages 
File (En,Fr) (Required).doc <== should match `En` and `Fr` 
File (Enfoo,Fr).doc   <== should match only `Fr` 
File (E,Fr).doc    <== should match only `Fr` 

私の現在の正規表現:

((\(|,)En(\)|,))|((\(|,)Fr(\)|,))|((\(|,)De(\)|,))|((\(|,)Es(\)|,))|((\(|,)It(\)|,))

それが何を意味する:

((\(|,) <== either starts with `open parenthesis` or `comma` (1) 
En  <== the language          (2) 
(\)|,)) <== either ends with `close parenthesis` or `comma` (3) 

その後、私はちょうど正規表現ORを追加(|)

あなたが見ることができるように、問題:regexr.com/3ev6pは、第二言語のスニペットがFrつまりがある場合、それは勝ったということです最初の言語スニペットEnがすでにopen parenthesisまたはcommaをキャプチャ/占有していて、第2言語スニペットFrが一致しないため、正規表現(1)を満たしていません。

enter image description here

あなたはすべての言語スニペットを完全にキャプチャする方法を知っていますか?私はPHPのpreg_match_all()を使用してこれらすべてを取得する予定です。誰かが助けることを願っています。 ありがとうございました!

+1

私が正しく理解しているかどうかわかりませんが、これはあなたが望むものですか? https://regex101.com/r/PAwqGg/1 – sinisake

+0

このhttp://regexr.com/3ev6sはどうですか? –

+1

@ Mi-創造性、境界はすべての言語を対象とする必要があります。 ;) – sinisake

答えて

3

正規表現は、言語コードの周りのコンマを消費しています。つまり、マッチを見つけた後、インデックスはカンマの後にあり、マッチすることができないので、そのカンマの後の言語は正規表現エンジンによってスキップされます。

の重複試合を一致させるために前後参照を使用することができます。

(?<=[(,])(En|Fr|De|Es|It)(?=[,)]) 
^^^^^^^^^    ^^^^^^^^ 

this regex demoを参照してください。

(?<=[(,])は、言語コードの前,(を必要と肯定後読みである、と(?=[,)])は言語コードの右側にカンマや)が必要ですが、コンマ/カッコが消費されていない肯定先読みで、それは次の反復の間に一致したままである。

ここで可能な別の解決方法は、単語境界の使用です(コメントに既に説明されています)。単語の境界は一致する全体の単語を助けます。

\b(En|Fr|De|Es|It)\b 

を参照してくださいregex demo

+0

うわー、私はまた、「肯定的な視点」や「肯定的な先読み」についても知らない。私は学校を飛ばしてはいけません。追加の説明のための答えとしてマーク。 –

1

これはすべてに一致する必要があります。preg_match_allに伴われ

(?<=,|\()(\w\w)(?=,|\)) 

は、仕事をする必要があります。

を説明:

  • を戻り読みアサーション(が先行されなければならない「」または 『(』)
  • 二つの単語文字(だから、あなたはあなたが事前にターゲットにされている言語を指定する必要はありません) 。
  • A先読みアサーション(続くべきである "" または ")")

を見て、それのthats。 :)

Working version

よろしくお願いいたします。

関連する問題