【问题标题】:Python regex: greedy pattern returning multiple empty matchesPython正则表达式:贪婪模式返回多个空匹配
【发布时间】:2023-03-30 20:10:02
【问题描述】:

这种模式只是简单地抓取字符串中的所有内容,直到数据中第一个潜在的句子边界:

[^\.?!\r\n]*

输出:

>>> pattern = re.compile(r"([^\.?!\r\n]*)")
>>> matches = pattern.findall("Australians go hard!!!") # Actual source snippet, not a personal comment about Australians. :-)
>>> print matches
['Australians go hard', '', '', '', '']

来自 Python 文档:

re.findall(pattern, string, flags=0)

返回字符串中所有不重叠的模式匹配,作为一个列表 字符串。从左到右扫描字符串,并返回匹配项 按照找到的顺序。如果模式中存在一个或多个组, 返回组列表;这将是一个元组列表,如果模式 有多个组。结果中包含空匹配项 除非他们触及另一场比赛的开始。

现在,如果从左到右扫描字符串并且 * 运算符是贪婪的,那么返回的第一个匹配项是直到感叹号的整个字符串是完全合理的。但是,在消耗完该部分之后,我看不到该模式如何准确地产生四次空匹配,大概是通过在“d”之后向左扫描字符串。我明白 * 运算符意味着这个模式可以匹配空字符串,我只是不明白它会如何在字母的尾随“d”和前导“!”之间多次这样做。标点符号。

添加 ^ 锚点有这样的效果:

>>> pattern = re.compile(r"^([^\.?!\r\n]*)")
>>> matches = pattern.findall("Australians go hard!!!")
>>> print matches
['Australians go hard']

由于这消除了空字符串匹配,这似乎表明所述空匹配发生在字符串的前导“A”之前。但这似乎与按照找到的顺序返回匹配项的文档相矛盾(前导“A”之前的匹配项应该是第一个),而且,恰好四个空匹配项让我感到困惑。

【问题讨论】:

    标签: python regex pattern-matching


    【解决方案1】:

    * 量词允许模式捕获长度为零的子字符串。在您的原始代码版本中(前面没有 ^ 锚点),其他匹配项是:

    • hard 结尾和第一个 ! 之间的零长度字符串
    • 第一个和第二个!之间的零长度字符串
    • 第二个和第三个!之间的零长度字符串
    • 第三个!和文本结尾之间的零长度字符串

    如果你喜欢here,你可以进一步切片/切块。

    现在将 ^ 锚点添加到前面可确保只有单个子字符串可以匹配该模式,因为输入文本的开头恰好出现一次。

    【讨论】:

    • 啊,是的。我一直在寻找任何出现的 4 件事,但我没有看到这种可能性。非常感谢。
    • @Schemer 如果我的解释有帮助,我很高兴。当我第一次开始使用正则表达式时,不重叠的零长度字符串对我来说确实很奇怪。
    • 你帮了大忙!而且你的回答很清楚。我一直在误解下一场可能的比赛必须在最后一场比赛结束时开始。我只是没有在这个概念之外思考——即使我一开始就不应该拥有它。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 2017-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多