簡體   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