正则表达式包括具有相同开始的重叠匹配

bob*_*ack 5 python regex python-3.x

我正在使用Python 3.6。

我的目标是匹配一个可能匹配多个字符串、重叠和/或从同一位置开始的正则表达式,例如:

re.findall('B.*A','BADACBA')
Run Code Online (Sandbox Code Playgroud)

这使:

['BADACBA']
Run Code Online (Sandbox Code Playgroud)

但我想要:

['BADACBA','BADA','BA','BA']
Run Code Online (Sandbox Code Playgroud)

(第二个是因为字符串中'BA'有两个实例)'BA'

根据如何使用正则表达式查找重叠匹配的建议?,我尝试将其包含在前瞻中:

re.findall('(?=(B.*A))','BADACBA')
Run Code Online (Sandbox Code Playgroud)

这使:

['BADACBA', 'BA']
Run Code Online (Sandbox Code Playgroud)

哪个更好,但仍然不是我想要的。

我也尝试过该regex模块:

regex.findall('B.*A','BADACBA',overlapped=True)
Run Code Online (Sandbox Code Playgroud)

但它仍然返回:

['BADACBA', 'BA']
Run Code Online (Sandbox Code Playgroud)

我还没能找到能找到所有匹配项的东西。由于我有很多这样的正则表达式,因此硬编码的解决方案没有多大帮助。有没有一个模块/函数可以做到这一点?

谢谢!

zwe*_*wer 3

正如我上面所说,正则表达式是一种主要是线性且仅限单规则的引擎 - 您可以在贪婪捕获或不贪婪捕获之间进行选择,但不能同时选择两者。此外,大多数正则表达式引擎不支持重叠匹配(甚至那些支持它的人也会用子字符串/强制头部移动来伪造它),因为它也不符合正则表达式哲学。

如果您只想查找两个子字符串之间的简单重叠匹配,您可以自己实现:

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
Run Code Online (Sandbox Code Playgroud)

这将产生:

substrings = find_substrings("BADACBA", "B", "A")
# ['BA', 'BADA', 'BADACBA', 'BA']
Run Code Online (Sandbox Code Playgroud)

但您必须修改它才能进行更复杂的匹配。