web-dev-qa-db-ja.com

正規表現後読みは、数量詞(「+」または「*」)では機能しません

正規表現で後読みを使用しようとしていますが、期待どおりに動作しないようです。したがって、これは私の実際の使用法ではありませんが、簡単にするために例を示します。 「これは例です」という文字列で「例」を照合したいとします。したがって、後読みの私の理解によれば、これはうまくいくはずです:

(?<=this\sis\san\s*?)example

これは、「this is an」、スペース文字の順に検索し、最後に「example」という単語に一致するようにします。今、それは動作せず、なぜかわかりません、後読み内で「+」または「*」を使用することは不可能ですか?

私もそれら2つを試してみましたが、正しく機能しましたが、私のニーズを満たしていません。

(?<=this\sis\san\s)example
this\sis\san\s*?example

このサイトを使用して正規表現をテストしています: http://gskinner.com/RegExr/

29
Noel De Martin

多くの正規表現ライブラリでは、次のようなアサーションの背後で厳密な表現のみを使用できます。

  • 同じ固定長の文字列のみに一致:(?<=foo|bar|\s,\s)(それぞれ3文字)
  • 固定長の文字列のみに一致:(?<=foobar|\r\n)(固定長の各ブランチ)
  • 上限の長さの文字列のみに一致:(?<=\s{,4})(最大4回の繰り返し)

これらの制限の理由は、主にこれらのライブラリが正規表現をまったく逆に処理できないか、限られたサブセットしか処理できないためです。

もう1つの理由は、いわゆる 病理学的動作ReDoS も参照)があるため、作成者が処理が重すぎる複雑な正規表現を作成しないようにすることです。

Regular-Expressions.info後読みアサーションの制限に関するセクション も参照してください。

28
Gumbo

python変数のアサーションビハインドアサーションを使用していない場合は、一致をエスケープして_\K_を使用してやり直すことにより、正規表現エンジンをだますことができます。

このサイトはそれをよく説明しています.. http://www.phpfreaks.com/blog/pcre-regex-spotlight-k ..

しかし、一致する式があり、\ Kを使用してその背後にあるすべてのものを取得したい場合は、ほとんどの場合、最初からやり直す必要があります...

例:

_string = '<a this is a tag> with some information <div this is another tag > LOOK FOR ME </div>'
_

/(\<a).+?(\<div).+?(\>)\K.+?(?=\<div)/を一致させると、終了divタグを一致させた後に正規表現が再起動するため、正規表現では結果に含まれません。 _(?=\div)_は、エンジンが終了divタグの前にすべてを取得するようにします

11
Leon

アンバーが言ったことは真実ですが、別のアプローチでそれを回避することができます:非キャプチャ括弧グループ

(?<=this\sis\san)(?:\s*)example

それはfixed長さの後ろを見るので、うまくいくはずです。

6
Bohemian

部分式を使用できます。

(this\sis\san\s*?)(example)

したがって、グループ2を取得するには、「example」、正規表現の場合は$2、フォーマット文字列を使用している場合は\2(Pythonのre.subなど)

0
WizKidd

ほとんどの正規表現エンジンは、後読みアサーションの可変長式をサポートしていません。

0
Amber