如果在python中使用正则表达式不包含某个关键字,我试图匹配文件路径的一部分。例如,将正则表达式应用于“/ exclude / this / test / other”不应该匹配,而“/ this / test / other”应该返回不包括“other”的文件路径,即“/ this / test”,以及其他“其他”是任何目录。到目前为止我正在使用这个
In [153]: re.findall("^(((?!exclude).)*(?=test).*)?", "/exclude/this/test/other")
Out[153]: [('', '')]
re.findall("^(((?!exclude).)*(?=test).*)?", "/this/test/other")
Out[152]: [('/this/test/other', '/')]
但我不能让它在“测试”之后停止匹配,也有一些空的匹配。有什么想法吗?
答案 0 :(得分:2)
如果您只需要检查关键字是否存在,只需使用in
:
In [33]: s1="/exclude/this/test"
In [34]: s2="this/test"
In [35]: 'exclude' in s1
Out[35]: True
In [36]: 'exclude' in s2
Out[36]: False
编辑: 或者如果你想要路径直到测试:
if 'exclude' not in s:
re.findall(r'(.+test)',s)
答案 1 :(得分:2)
您获得了额外的结果,因为(1)您使用findall()
代替search()
,以及(2)您正在使用捕获组而不是非捕获
>>> import re
>>> re.search(r'^(?:(?:(?!exclude).)*(?=test)*)$', "/this/test").group(0)
'/this/test'
这也适用于findall()
,但是当你匹配整个字符串时,这没有用。更重要的是, include 部分正则表达式不起作用。检查一下:
>>> re.search(r'^(?:(?:(?!exclude).)*(?=test)*)$', "/this/foo").group(0)
'/this/foo'
这是因为*
中的(?=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
或/exclude
。
答案 2 :(得分:1)
如果您的匹配比使用in
和简单关键字更复杂,那么您可能会更清楚地了解两个正则表达式:
import re
s1="/exclude/this/test"
s2="this/test"
for s in (s1,s2):
if re.search(r'exclude',s):
print 'excluding:',s
continue
print s, re.findall(r'test',s)
打印:
excluding: /exclude/this/test
this/test ['test']
如果这是您的目标,您可以将两个正则表达式压缩:
print [(s,re.findall(r'test',s)) for s in s1,s2 if not re.search(r'exclude',s)]
修改强>
如果我理解你的编辑,这可行:
s1="/exclude/this/test/other"
s2="/this/test/other"
print [(s,re.search(r'(.*?)/[^/]+$',s).group(1)) for s in s1,s2 if not re.search(r'exclude',s)]
打印:
[('/this/test/other', '/this/test')]