4

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

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

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

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

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

编辑:

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

4

3 回答 3

7

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

[m.start() for m in re.finditer('(?={0})'.format(re.escape(p3)), p1)]
于 2013-09-21T14:29:11.523 回答
2

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

>>> word = 'tryt'
>>> text = 'trytryt'
>>> [i for i, _ in enumerate(text) if text.startswith(word, i)]
[0, 3]
于 2013-09-21T16:27:49.097 回答
0

您正在这样做(或语法变体):

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

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

于 2013-09-21T14:39:20.783 回答