【问题标题】:How to get all overlapping matches in python regex that may start at the same location in a string?如何在 python 正则表达式中获取所有可能从字符串中相同位置开始的重叠匹配?
【发布时间】:2019-04-11 08:40:06
【问题描述】:

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

我尝试使用正则表达式模块,而不是默认的 re 模块来引入重叠 = True 参数,但它仍然缺少一些匹配项。

尝试通过更简单的插图来描述我的问题:

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

尝试了以下代码:

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']

【问题讨论】:

  • 请编辑问题以表明您的字符串不仅仅是字母。

标签: python regex


【解决方案1】:

Regex 在这里不是合适的工具,我建议:

  • 识别输入字符串中首字母的所有索引
  • 识别输入字符串中第二个字母的所有索引
  • 根据这些索引构建所有子字符串

代码:

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']

【讨论】:

  • 感谢 Allan 抽出时间来回答,但这是对原始问题的一个更简单的说明。在原始问题中,字符串 'axaybzb' 是一个更大的非结构化文本 ~ 5000 个字符,而 'a' 和 'b' 不是单个字符,而是字符串(单词)本身。
  • VPfB:对不起,我现在在火车上,稍后会编辑。谢谢你:)
【解决方案2】:

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

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 demo

警告:请注意,如果您有一个模式检查左手或右手上下文,并且在模式的任一端都有前瞻或后瞻,这将不起作用,因为迭代时此上下文将丢失在字符串上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 2013-04-16
    相关资源
    最近更新 更多