7

Javascriptでは、文字列がabcdefあり、この奇妙な動作を理解できません:

  • (?=abc)def文字列と一致しません
  • abc(?=def)文字列に一致します

なんで?

4

4 に答える 4

19

キャプチャでは幅がゼロであり(?=abc)def(?=abc)一致が成功した後、入力文字列内でカーソルを前方に移動しません。この構文は単に、次の 3 文字を先読みして、それらがabcであるかどうかを確認し、それらが である場合は、同じ文字が であるかどうかを確認する と言っているだけdefです。この時点で、マッチは失敗します。

一致を完了するには、正規表現エンジンがどのように機能するかを理解する必要があります。abcdef入力文字列と正規表現を考慮してくださいabc(?=def)。エンジンは最初に を照合し、a次に入力文字列内のカーソルを次の文字に移動して を照合しようとします。b入力文字列内のカーソルが一致にあるためbです。次に、エンジンはカーソルを入力文字列内に移動し、一致を試みcます。カーソルは入力文字列内にあるためc、一致は成功し、入力文字列内のカーソルは再び次の文字に移動します。エンジンはこの時点で に遭遇(?=def)し、入力文字列内のカーソル位置から次の 3 文字が実際に存在するかどうかを確認するために先を見越します。defカーソルを移動せずに、一致が正常に完了します。

次に、入力文字列xyzと正規表現を考えてみましょうx(?=y)Z。正規表現エンジンは、入力文字列の最初の文字にカーソルを置き、それが an であることを確認し、それxを見つけたxので、カーソルを入力文字列の次の文字に移動します。次に、次の文字が であるかどうかを確認しますyが、エンジンは入力テキスト カーソルの前の単語を移動しないため、入力テキストのカーソルは に留まりますy。次に、エンジンはカーソルが文字上にあるかどうかを確認しますがz、入力テキストのカーソルがまだ文字上にあるためy、一致は失敗します。

http://www.regular-expressions.info/lookaround.htmlで、正と負の両方の先読みについて詳しく読むことができます 。

于 2013-06-10T01:23:22.947 に答える
4

(?=...)つまり、右側の文字列をテストします。先読みは、文字を食べないゼロ幅のアサーションであることにも注意してください。あなたの最初の例では:(?=abc)つまり、その後に遭遇が続く必要がありますabcdef。これがパターンが失敗する理由です。

def2番目の例では、 afterが見つかりabc、文字列が一致します

于 2013-06-10T01:26:49.797 に答える
2

私のコメントに対するあなたの反応に基づいて、あなたが望むのは前向きな後読みだと思います:

(?<=abc)def

編集:

JavaScript を使用しているので (申し訳ありませんが、私はあなたの質問を読んだだけで、タグを見ていませんでした)、通常のキャプチャ グループを使用して、置換パターンに一致を含めてみませんか?

"abcdef".replace(/(abc)def/, "$1")
于 2013-06-10T01:37:56.270 に答える
2

javascriptでの先読みの MDN 定義

x(?=y)
「x」の後に「y」が続く場合にのみ、「x」と一致します。これを先読みと呼びます。

たとえば、/Jack(?=Sprat)/「Sprat」が後に続く場合にのみ「Jack」と一致します。/Jack(?=Sprat|Frost)/'Sprat' または 'Frost' が続く場合にのみ 'Jack' に一致します。ただし、「Sprat」も「Frost」も試合結果には含まれません。

So(?=y)の前に別のステートメント (この場合は空の文字列) がある場合、最初のステートメントの後に 2 番目のステートメントが続く場合にのみ一致します。先頭のステートメントがない場合、式(?="abc")は最初の 3 文字 abc をキャプチャせずに一致し、それらの文字が def であるかどうかを再度確認しますが、これは失敗します。

于 2013-06-10T01:23:41.063 に答える