搜索特定子字符串的正则表达式

时间:2018-05-23 21:58:51

标签: python regex

我试过这段代码:

re.findall(r"d.*?c", "dcc")

搜索带有第一个字母d和最后一个字母c的子字符串。

但我得到输出['dc']

正确的输出应为['dc', 'dcc']

我做错了什么?

4 个答案:

答案 0 :(得分:0)

使用我所知道的任何内置正则表达式函数,您所寻找的内容是不可能的。 re.findall()仅返回非重叠匹配。在匹配dc之后,它会在此之后查找另一个匹配项。由于字符串的其余部分仅为c,并且不匹配,因此它已完成,因此只返回["dc"]

当您使用像*这样的量词时,您可以选择让它变得贪婪或非贪婪 - 或者找到正则表达式的最长或最短匹配。要做你想做的事,你需要一种方法来告诉它连续寻找更长的匹配,直到它找不到任何东西。没有简单的方法可以做到这一点。您可以使用具有特定计数的量词,但您必须在代码中循环它:

d.{0}c
d.{1}c
d.{2}c
d.{3}c
...

如果你有一个包含多个量化子模式的正则表达式,你必须尝试所有长度组合。

答案 1 :(得分:0)

你的两个问题是.*贪婪而.*?是最小的,而re.findall()只返回非重叠的匹配。这是一个可能的解决方案:

def findall_inner(expr, text):
    explore = list(re.findall(expr, text))
    matches = set()
    while explore:
        word = explore.pop()
        if len(word) >= 2 and word not in matches:
            explore.extend(re.findall(expr, word[1:])) # try more removing first letter
            explore.extend(re.findall(expr, word[:-1])) # try more removing last letter
        matches.add(word)
    return list(matches)

found = findall_inner(r"d.*c", "dcc")
print(found)

这有点过分,使用findall而不是搜索并使用>= 2代替> 2,因为在这种情况下,d.*c只能有一个非重叠匹配并且单字符字符串与模式不匹配。但是它有一些灵活性取决于你可能想要的其他类型的模式。

答案 2 :(得分:-1)

试试这个正则表达式:

^d.*c$

基本上,您正在寻找字符串的开头为d,字符串的结尾为c。

答案 3 :(得分:-2)

这是一个非常重要的要点:正则表达式引擎始终返回最左边的匹配,即使是更好的"匹配可以在以后找到。将正则表达式应用于字符串时,引擎从字符串的第一个字符开始。它会在第一个字符处尝试正则表达式的所有可能排列。只有在尝试了所有可能性并且发现失败时,引擎才会继续使用文本中的第二个字符。因此,当它找到[' dc']然后引擎通过' dc'并继续第二个'。所以不可能与[' dcc']匹配。