2017-04-24 21 views
3

私はC#を使用します。私は文字列を持っています:正規表現。 2つの単語間の特定の単語に一致する

wordA wordB wordC wordB wordD 

wordAとwordDの間のすべての単語Bを一致させる必要があります。 私はこのようなwordAと単語の間にすべてを一致させるために先読みと後読みを使う:

(?<=wordA)(.*?)(?=wordD) 

しかし

(?<=wordA)(wordB)(?=wordD) 

のようなものは何にもマッチしません。 wordAとwordDの間のwordBのすべての一致を照合する最良の方法は何ですか?

+0

(これは括弧で囲まれているため)単語をキャプチャしたいと思われるようです。そうであれば、もっと汎用的な変種 '\ bfirst \ b。* \ b(second)\ b。* \ bthird \ b'を[regex101](https://regex101.com)/r/SUYwrQ/2)。違いは、これは*最初の単語から3番目までのすべてにマッチしますが、* 2番目の単語だけをキャプチャする点です。これは望ましくない動作である可能性があります。もしそうであれば、@WiktorStribiżewによって行われるルックアラウンドアプローチがそれを行います。より一般的なもの以外に、私はこれがWiktorsのアプローチに何もないとは思わない。 – ClasG

答えて

4

前後参照に.*?を入れて:

(?<=wordA.*?)wordB(?=.*?wordD) 

は今regex demo

を参照してください、パターンが意味:

  • (?<=wordA.*?)を - (正の後読み)wordAの存在が続く必要です直前に0以上の文字(可能な限り)を使用してください。
  • wordB - ワード
  • (?=.*?wordD) B
  • - (正の先読み)は(可能な限り少数のような)任意の0+文字の存在を必要とするそれらの後 wordD(したがって、それは wordB後またはいくつかの文字の後に右であることができる)を用いて行きました。

あなたは、複数行の入力を占めRegexOptions.Singlelineフラグを使用して正規表現をコンパイル.は、改行記号と一致することができるように( - (?s)(?<=wordA.*?)wordB(?=.*?wordD)または(?s)インライン修飾子オプションのパターンを付加)する必要がある場合。

「言葉」は、文字/数字/アンダースコアで構成されており、あなたが単語全体としてそれらを一致させる必要がある場合は、\b S(ワード境界)でwordAwordBwordDをラップすることを忘れないでください。

常にターゲット環境で、あなたの正規表現をテスト:

var s = "wordA wordB wordC wordB \n wordD"; 
var pattern = @"(?<=wordA.*?)wordB(?=.*?wordD)"; 
var result = Regex.Replace(s, pattern, "<<<$&>>>", RegexOptions.Singleline); 
Console.WriteLine(result); 
// => wordA <<<wordB>>> wordC <<<wordB>>> 
// wordD 

C# demoを参照してください。

+0

あなたが与えたデモで完璧に動作します。しかし、私はregex101.comで同様に試していましたが、そこには誤りがありました。異なるオンラインコンパイラの違いはありますか?私はここにURLを保存しましたhttps://regex101.com/r/ORkgjg/1 – Utsav

+0

@Utsav:なぜWebサイトがサポートしていない場合、**。NET **正規表現をテストするのにhttp://regex101.comを使用していますか? .NETの正規表現の構文?質問はC#でタグ付けされています。答えに追加したC#のデモを参照してください。 –

+0

それを知らなかった。ありがとう。 – Utsav

関連する問題