好的,我发现了这个:Find all occurrences of a substring in Python
其中说,为了使索引重叠列表中的子串的出现,您可以使用:
[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]
。
答案 0 :(得分:7)
re.finditer
的参数是简单的字符串。如果变量中有子字符串,只需将其格式化为正则表达式即可。像'(?={0})'.format(p3)
之类的东西就是一个开始。由于RE中的various symbols do have special meaning,您将要逃避它们。幸运的是,re
module包括re.escape
以满足这种需求。
[m.start() for m in re.finditer('(?={0})'.format(re.escape(p3)), p1)]
答案 1 :(得分:1)
正则表达式在这里可能有点矫枉过正:
>>> word = 'tryt'
>>> text = 'trytryt'
>>> [i for i, _ in enumerate(text) if text.startswith(word, i)]
[0, 3]
答案 2 :(得分: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
这是我能想到的最快的方法。