【问题标题】:RegEx non-greedy quantifier .*? not working as expected正则表达式非贪婪量词 .*?没有按预期工作
【发布时间】:2021-09-21 07:56:40
【问题描述】:

我正在尝试创建一个正则表达式来匹配以下字符串中的“section 2 foo 2019 foo”(一个最小的例子,不是真实的):

section 1 bar bar section 2 foo 2019 foo section 3 bar 2021 bar end 

(字符串“section”,后跟数字,后跟任意文本,后跟 4 位数年份,再后跟任意文本)

我最初的想法是使用非贪婪量词和一个捕获组和一个非捕获组,如下所示:

(section [0-9]{1}.*?(19|20)[0-9]{2}.*?)(?:section)

但是,这将为捕获组生成以下匹配项:

section 1 bar section 2 foo 2019 foo

所以,它也匹配第 1 部分,我想排除它。

经过一些背景阅读,我明白这里的问题是“非贪婪”实际上并不意味着“匹配最短的可能字符串”,而是意味着“匹配从左到右读取的最短可能字符串而不回溯”。

这里有一些关于这个问题的答案,但我仍在努力为这个特殊情况找到正确的正则表达式。我尝试使用具有负前瞻的非捕获组,如下所示:

section [0-9]{1,2}(?:(?!section [0-9]{1}).).*(?!202[1-9]{1})[0-9]{4} .*?

但这仍然会匹配第一个不需要的部分,出乎意料。 知道我的想法可能错在哪里吗?

【问题讨论】:

    标签: regex regex-lookarounds regex-greedy


    【解决方案1】:

    这里的问题是,使用.*? 作为“任何”文本部分仍然有可能匹配匹配或不匹配的部分,直到找到一个结束年份。您尝试使用回火点的最终正则表达式在正确的轨道上。考虑这个版本:

    \bsection \d+ (?:(?!\bsection \d+).)*?(?:19|20)\d{2}\b
    

    Demo

    解释:

    \bsection \d+             match "section" followed by a number and space
    (?:(?!\bsection \d+).)*?  match any content, without crossing over to another section
    (?:19|20)\d{2}\b          match a 4 digit year
    

    【讨论】:

    • 非常感谢蒂姆,您的快速回复和详细回答。这看起来很棒。为了记录和任何(像我一样)偶然发现“tempered dot”这个词的人,这里有一个解释:stackoverflow.com/questions/30900794/…
    猜你喜欢
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 2010-10-20
    • 2013-02-15
    相关资源
    最近更新 更多