[英]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.