如何在Python正则表达式中获取所有重叠的匹配项,这些匹配项可能从字符串的相同位置开始?

3

如何在Python中获取具有多个起始和结束点的字符串中所有可能的重叠匹配。

我尝试使用regex模块,而不是默认的re模块来引入overlapped = True参数,但仍然缺少一些匹配项。

试图通过更简单的例子描述我的问题:

查找以a开头并以b结尾的字符串(axaybzb)中所有可能的组合。

尝试以下代码:

import regex

print(regex.findall(r'a\w+b','axaybzb', overlapped=False))

['axaybzb']

print(regex.findall(r'a\w+?b','axaybzb', overlapped=False))

['axayb']

print(regex.findall(r'a\w+b','axaybzb', overlapped=True))

['axaybzb', 'aybzb']

print(regex.findall(r'a\w+?b','axaybzb', overlapped=True))

['axayb', 'ayb']

预期输出应该是:
['axayb', 'axaybzb', 'ayb', 'aybzb']

请编辑问题以显示您的字符串不仅仅是字母。 - Wiktor Stribiżew
2个回答

1
正则表达式在这里不是合适的工具,我建议:
  • 识别输入字符串中第一个字母的所有索引
  • 识别输入字符串中第二个字母的所有索引
  • 基于这些索引构建所有子字符串

代码:

def find(str, ch):
    for i, ltr in enumerate(str):
        if ltr == ch:
            yield i

s = "axaybzb"
startChar = 'a'
endChar = 'b'

startCharList = list(find(s,startChar))
endCharList = list(find(s,endChar))

output = []
for u in startCharList:
    for v in endCharList:
           if u <= v:
               output.append(s[u:v+1])
print(output)

输出:

$ python substring.py 
['axayb', 'axaybzb', 'ayb', 'aybzb']

感谢艾伦抽出时间来回答问题,但这是原问题的一个更简单的示例。在原问题中,字符串“axaybzb”是一个更大的非结构化文本,约5000个字符,“a”和“b”不是单个字符,而是字符串(单词)本身。 - mojø_jojø
VPfB:抱歉,我现在在火车上,稍后会编辑。谢谢 :) - Allan

1

使用像您这样的简单模式,您可以生成字符串中所有连续字符的切片,并将它们全部与特定的正则表达式进行全匹配测试:

import re

def findall_overlapped(r, s):
  res = []                     # Resulting list
  reg = r'^{}$'.format(r)      # Regex must match full string
  for q in range(len(s)):      # Iterate over all chars in a string
    for w in range(q,len(s)):  # Iterate over the rest of the chars to the right
        cur = s[q:w+1]         # Currently tested slice
        if re.match(reg, cur): # If there is a full slice match
            res.append(cur)    # Append it to the resulting list
  return res

rex = r'a\w+b'
print(findall_overlapped(rex, 'axaybzb'))
# => ['axayb', 'axaybzb', 'ayb', 'aybzb']

请查看Python演示

警告: 请注意,如果您在模式检查左侧或右侧上下文,并且在模式的任一端使用了前瞻或后顾,则此上下文将在迭代字符串时丢失,因此此方法无法正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接