findall()(1)の代わりに使用search()し、(2)非キャプチャの代わりにキャプチャグループを使用しているため、追加の結果が得られます。
>>> import re
>>> re.search(r'^(?:(?:(?!exclude).)*(?=test)*)$', "/this/test").group(0)
'/this/test'
これも機能しfindall()ますが、文字列全体を一致させる場合は、実際には意味がありません。さらに重要なのは、正規表現のインクルード部分が機能しないことです。これをチェックして:
>>> re.search(r'^(?:(?:(?!exclude).)*(?=test)*)$', "/this/foo").group(0)
'/this/foo'
これは、*in(?=test)*によって先読みがオプションになり、意味がなくなるためです。しかし、を取り除くこと*は実際には解決策ではありません。なぜならexclude、testはやのような長い単語の一部である可能性があるからexcludexxですyyytest。これがより良い正規表現です:
r'^(?=.*/test\b)(?!.*/exclude\b)(?:/\w+)+$'
テスト済み:
>>> re.search(r'^(?=.*/test\b)(?!.*/exclude\b)(?:/\w+)+$', '/this/test').group()
'/this/test'
>>> re.search(r'^(?=.*/test\b)(?!.*/exclude\b)(?:/\w+)+$', '/this/foo').group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
編集:「オプションの先読み」の問題を修正したようですが、正規表現全体がオプションになりました。
編集:後で一致を停止したい場合は/test、これを試してください:
r'^(?:/(?!test\b|exclude\b)\w+)*/test\b'
(?:/(?!test\b|exclude\b)\w+)*/testまたはでない限り、0個以上のパスコンポーネントに一致します/exclude。