【问题标题】:Python regular expression question mark operator not working?Python正则表达式问号运算符不起作用?
【发布时间】:2013-01-02 01:26:05
【问题描述】:
import re
str='abc defg'
m1 = re.match(".*(def)?",str)
m2 = re.match(".*(def)",str)
print (m1.group(1),m2.group(1))

上面的输出是:

(无,'def')

发生了什么事?即使使用非贪婪重复运算符,可选的捕获组(def)? 也不匹配。

【问题讨论】:

    标签: python regex capture optional


    【解决方案1】:

    当正则表达式引擎尝试匹配 .*(def)abc defg 时会发生以下情况:

    • 首先,引擎开始尝试匹配字符串开头的正则表达式。
    • 贪婪子模式.* 最初会尝试尽可能多地匹配,匹配整个字符串。
    • 由于这会导致其余的匹配失败,正则表达式引擎会回溯,直到找到匹配 (def) 的方法,当 .* 仅匹配 abc  时会发生这种情况。

    但是,如果我们将正则表达式更改为 .*(def)?,则会发生以下情况:

    • 首先,正则表达式引擎再次从字符串的开头开始。
    • 接下来,它再次尝试尽可能多地匹配.*,匹配整个字符串。
    • 但此时,由于正则表达式的所有其余部分都是可选的,因此它找到了整个正则表达式的匹配项!由于(def)? 是贪婪的,所以引擎 更愿意匹配它,但它不会回溯早期的子模式来看看它是否可以。相反,它只会让.* 吞噬整个字符串,而不会为(def)? 留下任何东西。

    .*?(def).*?(def)? 也会发生类似的情况:

    • 同样,引擎从字符串的开头开始。
    • 不贪婪的子模式 .*? 尝试匹配 少数 次,即根本不匹配。
    • 此时,(def) 无法匹配,但 (def)? 可以。因此,对于(def),正则表达式引擎必须返回并考虑.*? 的更长匹配,直到它找到一个让完整模式匹配的匹配,而对于(def)?,它不必这样做,所以它没有不。

    有关详细信息,请参阅"Combining RE Pieces" section of the Perl regular expressions manual(它与 Python 的“Perl 兼容”正则表达式的行为相匹配)。

    【讨论】:

    • 很抱歉直到现在我才接受您的回答。我是论坛的新手,对事情不确定。并感谢您的全面解释。我之前实际上已经写过一个正则表达式引擎,所以我应该能够弄清楚这一点。
    猜你喜欢
    • 2015-06-22
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 2012-10-30
    • 2023-03-10
    • 2020-08-31
    • 2019-01-01
    相关资源
    最近更新 更多