你得到了额外的结果,因为(1)你使用findall()
而不是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)*
使前瞻成为可选的,这使得它毫无意义。但是摆脱 the*
并不是真正的解决方案,因为exclude
andtest
可能是较长单词的一部分,例如excludexx
or 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
or /exclude
。