173

これらの表現の意味を調べましたが、正確な違いはわかりませんでした。

これは彼らが言うことです:

  • ?:式を一致させますが、キャプチャしません。
  • ?=サフィックスに一致しますが、キャプチャから除外します。
  • ?!接尾辞がない場合に一致します。

これらを単純な正規表現で使用してみましたが、すべて同様の結果が得られました。

たとえば、次の 3 つの式は非常によく似た結果になります。

  • [a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?!\.[a-zA-Z0-9]+)*
  • [a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?=\.[a-zA-Z0-9]+)*
  • [a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9]+)*
4

6 に答える 6

234

?=との違い?!は、前者は特定の式が一致する必要があり、後者は一致しない必要があることです。たとえばa(?=b)、「ab」の「a」には一致しますが、「ac」の「a」には一致しません。一方a(?!b)、「ac」の「a」には一致しますが、「ab」の「a」には一致しません。

?:との違いは、一致全体から式?=?=除外し?:、キャプチャ グループを作成しないことです。たとえばa(?:b)、「abc」の「ab」と一致しますが、「abc」a(?=b)の「a」とのみ一致します。a(b)「abc」の「ab」に一致し、「b」を含むキャプチャを作成します

于 2012-05-29T18:43:02.283 に答える
122
?:  is for non capturing group
?=  is for positive look ahead
?!  is for negative look ahead
?<= is for positive look behind
?<! is for negative look behind

ここを確認してください: http://www.regular-expressions.info/lookaround.htmlで、正規表現の先読みに関する非常に優れたチュートリアルと例を確認してください。

于 2012-05-29T18:38:48.770 に答える
47

理解を深めるために、3 つの式とキャプチャ グループを適用して、それぞれの動作を分析してみましょう。

  • () キャプチャ グループ- 括弧内の正規表現が一致する必要があり、一致するとキャプチャ グループが作成されます
  • (?:) 非キャプチャ グループ- 括弧内の正規表現は一致する必要がありますが、キャプチャ グループは作成されません
  • (?=) 肯定的な先読み- 正規表現が一致する必要があることを表明します
  • (?!) 否定先読み- 正規表現に一致することが不可能であることを主張します

辞めるq(u)i申請をしましょう。はqに一致し、キャプチャ グループはuに一致します。キャプチャ グループ内の一致が取得され、キャプチャ グループが作成されます。したがって、エンジンは で続行します。そして、iに一致します。この最後の一致の試みは成功しました。quiが一致し、uを含むキャプチャ グループが作成されます。
qu

i
i

辞めるq(?:u)i申請をしましょう。ここでもqに一致し、非キャプチャ グループはuに一致します。非キャプチャ グループからの一致が取得されますが、キャプチャ グループは作成されません。したがって、エンジンは で続行します。そして、iに一致します。この最後の一致の試みは成功しました。quiが一致します。
qu

i
i

辞めるq(?=u)i申請をしましょう。先読みは肯定的で、その後に別のトークンが続きます。繰り返しますが、 quに一致します。ただし、先読みからの一致は破棄する必要があるため、エンジンは文字列からuに戻ります。先読みが成功したことを考えると、エンジンは を続行します。しかし、uと一致することはできません。したがって、この一致の試みは失敗します

qu
i
i
i

辞めるq(?=u)u申請をしましょう。先読みは肯定的で、その後に別のトークンが続きます。繰り返しますが、 quに一致します。ただし、先読みからの一致は破棄する必要があるため、エンジンは文字列からuに戻ります。先読みが成功したことを考えると、エンジンは を続行します。そしてuと一致します。したがって、この一致の試みは成功です。quが一致します。

qu
u
u
u

辞めるq(?!i)u申請をしましょう。この場合でも、先読みは肯定的であり (一致しないため)、別のトークンが続きます。繰り返しますが、 qに一致し、 uには一致しません。先読みからの一致は破棄する必要があるため、エンジンは文字列からuに戻ります。先読みが成功したことを考えると、エンジンは を続行します。そしてuと一致します。したがって、この一致の試みは成功です。quが一致します。
i
qi
u
u
u

したがって、結論として、先読みグループと非キャプチャ グループの本当の違いは、単に存在をテストするか、一致をテストして保存するかだけです。

ただし、キャプチャ グループはコストがかかるため、慎重に使用してください。

于 2016-08-15T22:20:14.630 に答える
8

これらと照合してみてくださいfoobar:

/foo(?=b)(.*)/
/foo(?!b)(.*)/

最初の正規表現は一致し、最初のサブマッチとして「bar」を返します — (?=b)「b」に一致しますが、それを消費せず、次の括弧に残します。

2 番目の正規表現は一致しません。これは、「foo」の後に「b」とは異なるものが続くことを想定しているためです。

(?:...)simple とまったく同じ効果(...)がありますが、その部分をサブマッチとして返しません。

于 2012-05-29T18:42:00.527 に答える
0

これが本当の違いです:

>>> re.match('a(?=b)bc', 'abc')
<Match...>
>>> re.match('a(?:b)c', 'abc')
<Match...>

# note:
>>> re.match('a(?=b)c', 'abc')
None

"?:" または "?=" の後の内容を気にしなければ、"?:" と "?=" はまったく同じです。どちらも使用OKです。

ただし、これらのコンテンツをさらに処理する必要がある場合 (全体を一致させるだけでなく、その場合は単に "a(b)" を使用できます)、代わりに "?=" を使用する必要があります。原因 "?:" はそのまま通過します。

于 2020-05-24T23:18:42.380 に答える