繁体   English   中英

查找所有出现的子字符串(包括重叠)?

[英]Find all occurrences of a substring (including overlap)?

好的,所以我发现了这个: 如何找到所有出现的子字符串?

也就是说,要获得列表中子字符串的重叠出现的索引,您可以使用:

[m.start() for m in re.finditer('(?=SUBSTRING)', 'STRING')]

哪个有效,但我的问题是要查找的字符串和子字符串都是由变量定义的。 我对正则表达式的了解不够,不知道如何处理它 - 我可以让它与不重叠的子字符串一起工作,这只是:

[m.start() for m in re.finditer(p3, p1)]

编辑:

因为有人问,所以我会继续指定。 p1 和 p3 可以是任何字符串,但如果它们是,例如p3 = "tryt"p1 = "trytryt" ,结果应该是[0, 3]

re.finditer的参数是简单的字符串。 如果变量中有子字符串,只需将其格式化为正则表达式即可。 '(?={0})'.format(p3)是一个开始。 由于各种符号在 RE 中确实具有特殊含义,因此您将需要对它们进行转义。 幸运的是re模块包含re.escape为了满足这种需要。

[m.start() for m in re.finditer('(?={0})'.format(re.escape(p3)), p1)]

正则表达式在这里可能有点矫枉过正:

>>> word = 'tryt'
>>> text = 'trytryt'
>>> [i for i, _ in enumerate(text) if text.startswith(word, i)]
[0, 3]

您正在执行此操作(或句法变体):

import re

needle = "(?=(aba))"
haystack = "ababababa"

[match.start() for match in re.finditer(needle, haystack)]
#>>> [0, 2, 4, 6]

哪个应该工作。

因此,问题可能是needle的形式不正确,“(?=(...))”(从您与 D.Shawley 的互动中可以明显看出这一点)。 在这种情况下,有几种选择。

如果您的子字符串是有效的正则表达式,您可以手动遍历可能的位置,进行匹配。

needle = re.compile(needle)
[i for i in range(len(haystack)) if needle.match(haystack, i)]
#>>> [0, 2, 4, 6]

如果您不想要任意的正则表达式而只是精确的子字符串匹配,那么完全避免正则表达式并使用以下方法会更清晰:

needle = "aba"
haystack = "ababababa"

[i for i in range(len(haystack)) if haystack.startswith(needle, i)]
#>>> [0, 2, 4, 6]

如果您正在寻找更快的结果,您可以扩展循环并使用.index来加快搜索速度:

def findall(needle, haystack):
    i = 0
    try:
        while True:
            i = haystack.index(needle, i)
            yield i
            i += 1

    except ValueError:
        pass

这是我能想到的最快的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM