【问题标题】:Find all occurrences of a substring (including overlap)?查找所有出现的子字符串(包括重叠)?
【发布时间】:2013-09-26 20:12:14
【问题描述】:

好的,所以我找到了这个:How to find all occurrences of a substring?

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

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

【问题讨论】:

  • 请发布p3p1 和预期输出。

标签: python regex string substring


【解决方案1】:

re.finditer 的参数是简单的字符串。如果变量中有子字符串,只需将其格式化为正则表达式。像'(?={0})'.format(p3) 这样的东西是一个开始。由于 various symbols do have special meaning 在 RE 中,您将想要逃避它们。幸运的是,re module 包含 re.escape 就是为了满足这种需求。

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

【讨论】:

  • 没用,但我将 '(=?{0})' 改回 '(?={0})' 并且效果很好。谢谢!
  • 很抱歉,但很乐意为您提供帮助。谢谢@hop
【解决方案2】:

Regex 在这里可能有点矫枉过正:

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

【讨论】:

    【解决方案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
    

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

    【讨论】:

    • 完全忽略了问题的重点。也很混乱。
    • 怎么样?最后一个 sn-p 正是所要求的;前两个假设“子字符串”可以定义为问题代码所暗示的任何正则表达式。
    • 首先你会无缘无故地重写 OPs 代码。然后:这个问题实际上是询问如何从另一个字符串构造一个字符串,您没有解决这个问题。另外,您写“哪个应该起作用”暗示它不起作用,但不要解释在什么情况下不起作用。我当然可以使用给定的正则表达式,为什么要改变它?然后你就离开了关于 O() 的切线,这与手头的主题完全无关。谈到复杂性:正则表达式版本完全将 strcmp 版本从水中吹出来,以获得更长的干草堆 - 只是 timeit。吃饱了吗?
    • “首先你无缘无故地重写 OPs 代码”。如果这很重要,我可以让它更类似于原版。 // “问题实际上是关于如何从另一个字符串构造一个字符串”。在哪里? // “你写了”which should work”暗示它不起作用,但不要解释在什么情况下它不起作用”。我做了,我会在编辑中澄清。 // “然后你继续 [on about] O()”。然而,这 相关的,即使 D.Shawley 的解决方案不需要涵盖它//“正则表达式版本 [更快]”。很公平。
    • +1 表示最后一个,这比使用enumeratefinditer很多,因为它是用C 实现的。(虽然它可以写一点更短,没有尝试/除了使用find)
    猜你喜欢
    • 2017-08-05
    • 2015-05-13
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 2021-08-20
    • 1970-01-01
    相关资源
    最近更新 更多