我正在使用Python 3.6。
我的目标是匹配可能匹配多个字符串,重叠和/或从同一位置开始的正则表达式,例如:
<i class="material-icons">close</i>
给出:
re.findall('B.*A','BADACBA')
但我想:
['BADACBA']
(第二个['BADACBA','BADA','BA','BA']
是因为字符串中有'BA'
的两个实例)
根据How to find overlapping matches with a regexp?的建议,我尝试将其封装在前瞻中:
'BA'
给出:
re.findall('(?=(B.*A))','BADACBA')
哪个更好,但仍然不是我想要的。
我也尝试了['BADACBA', 'BA']
模块:
regex
但它仍然会返回:
regex.findall('B.*A','BADACBA',overlapped=True)
我找不到能找到所有比赛的东西。由于我有很多这样的正则表达式,硬编码的解决方案无济于事。是否有模块/功能可以做到这一点?
谢谢!
答案 0 :(得分:1)
正如我上面所说,正则表达式是一种主要的线性和单一规则的引擎 - 您可以选择是否贪婪捕获,但不能同时选择两者。此外,大多数正则表达式引擎不支持重叠匹配(甚至那些支持它的人用子串/强制移动来伪造它)因为它也不适合正则表达式哲学。
如果您只查找两个子字符串之间的简单重叠匹配,可以自行实现:
def find_substrings(data, start, end):
result = []
s_len = len(start) # a shortcut for `start` length
e_len = len(end) # a shortcut for `end` length
current_pos = data.find(start) # find the first occurrence of `start`
while current_pos != -1: # loop while we can find `start` in our data
# find the first occurrence of `end` after the current occurrence of `start`
end_pos = data.find(end, current_pos + s_len)
while end_pos != -1: # loop while we can find `end` after the current `start`
end_pos += e_len # just so we include the selected substring
result.append(data[current_pos:end_pos]) # add the current substring
end_pos = data.find(end, end_pos) # find the next `end` after the curr. `start`
current_pos = data.find(start, current_pos + s_len) # find the next `start`
return result
将产生:
substrings = find_substrings("BADACBA", "B", "A")
# ['BA', 'BADA', 'BADACBA', 'BA']
但是你必须修改它才能进行更复杂的比赛。