我有这样的文件名:
xxx
xxx.suffix
xxx
xxx.suffix
我想找到所有的xxx(可能是任何东西,但不包含'.suffix')并删除后缀。
我试过(。*?)(。后缀)?我希望第一组能够非贪婪地匹配任何东西,而第二组则是可选的。
但这不起作用。我得到的是:
('', None)
我正在使用Python,代码是:
patt = re.compile(r'(.*?)(\.suffix)?')
print patt.match(str).groups()
编辑:显然以('。suffix')结尾也有效,但我不知道。
答案 0 :(得分:4)
空字符串是正则表达式的有效匹配,因此它与所有输入的匹配。
在正则表达式的末尾添加“$”(字符串结尾)表示您在匹配后不希望字符串中有更多数据。
>>> re.compile( r'(.*?)(\.suffix)?$' ).match("xxx.suffix" ).groups()
('xxx', '.suffix')
答案 1 :(得分:3)
当你使第一部分非贪婪时,它甚至在开始时匹配空字符串。由于第二部分是可选的,因此省略,因此None
。
另一种解决方案:
a = 'xxx xxx.suffix xxx xxx.suffix'
l = a.split()
patt = re.compile(r'(.*?)(\.suffix)?$')
print [patt.match(i).groups() for i in l]
打印
[('xxx', None), ('xxx', '.suffix'), ('xxx', None), ('xxx', '.suffix')]
为什么呢?因为现在,正则表达式使用$
锚定到字符串的末尾。
根据您计划对结果执行的操作,使用
可能也很有用patt = re.compile(r'(.*?)(\.suffix|)$')
它会为您''
而不是None
。这样可以简化琴弦的重新组装。
当然,问题是你真的需要正则表达式。
print [p[:2] for p in (i.partition('.suffix') for i in l)]
产生相同的结果
[('xxx', ''), ('xxx', '.suffix'), ('xxx', ''), ('xxx', '.suffix')]
并且速度更快:
>>> import timeit
>>> timeit.timeit(lambda: [p[:2] for p in (i.partition('.suffix') for i in l)])
2.1371913756093956
>>> timeit.timeit(lambda: [patt.match(i).groups() for i in l])
5.259215670919147
结果是1000000次呼叫所需的时间(以秒为单位)。
答案 2 :(得分:1)
为什么不使用endswith
?
>>> a = 'xxx xxx.suffix xxx xxx.suffix'
>>> a = a.split()
>>> a
['xxx', 'xxx.suffix', 'xxx', 'xxx.suffix']
>>> [s for s in a if s.endswith('.suffix')]
['xxx.suffix', 'xxx.suffix']
答案 3 :(得分:0)
我找到了一个解决方案,你不必先拆分。有关解释和正则表达式测试,调试等,请查看此处:http://regex101.com/r/aL7dQ2
a = """
xxx
xxx.suffix
xxx
xxx.suffix
"""
patt = re.compile(r'(\S+?\b)(\.suffix)?')
patt.findall(a)
<强>输出:强>
[('xxx', ''), ('xxx', '.suffix'), ('xxx', ''), ('xxx', '.suffix')]