【问题标题】:Regular expressions: Matching last occurence of a repeating pattern正则表达式:匹配重复模式的最后一次出现
【发布时间】:2018-03-26 21:00:46
【问题描述】:

有没有办法编写一个匹配最后一次出现的重复模式的正则表达式。例如:

用这段文字:

server_name{abc.com;随机文本;} server_name{xyz.com;更多文字;}

匹配应该是server_name{xyz.com;更多文字;}

还有文字:

server_name{abc.com;随机文本;} server_name{cde.com 更随机 文本;} server_name{xyz.com;更多文字;}

匹配仍然是 server_name{xyz.com;更多文字;}

{} 之间的内容可能会有所不同。并且正则表达式将始终仅匹配带有 server_name{whatever text here;}

的最后一个模式

我一直在用https://www.regexpal.com/ 进行测试 以下正则表达式匹配所有 server_name{} -模式,而不仅仅是最后一个。我尝试使用负前瞻,但没有成功。

server_name\{(.|\n)+?;\}

【问题讨论】:

    标签: regex


    【解决方案1】:

    编辑:这个答案依赖于 PCRE、Perl 等中可用的 \K 令牌,因为 OP 没有指定他的正则表达式的风格。

    .*\K 添加到正则表达式的开头。它匹配任意数量的任意字符,然后重置报告的匹配。

    根据 ctwheels 的建议,我已将您的 (.|\n) 更改为 [\s\S](匹配任何空白或非空白字符)。

    完整的正则表达式:

    .*\Kserver_name\{[\s\S]+?;\}
    

    在线试用here

    【讨论】:

    • \K 元字符对我来说是新的,所以here's some more info 对其他人来说也是新的。
    • 很高兴知道顺便说一句。但是,我对这个答案的担忧是 \K 有点特定于正则表达式风格的子集,但 OP 没有指定他使用的语言/风格。这可能值得澄清。
    • 在引入\K令牌之前,一定要确定OP使用的是哪种语言。此外,使用带有DOTALL 标志的[\s\S]. 比使用(.|\n) 好得多。它的性能好多了,并且不会无缘无故地创建一个组。
    • @ctwheels 同意——我刚刚复制了 OP 的正则表达式。
    • @O.O.Balance 你应该改进他们最初的想法,给他们最好的方法(或者你认为最好的方法)。您有权更改 OP 发布的内容以获得更好的工作代码集。这不仅改进了 OP 的代码,而且还带来了一个更好的整体 SO 社区,因为其他用户可能会使用您的代码(或其中的一部分)。不要犹豫,添加您认为有益的其他更改,并让 OP 知道您为什么要进行这些更改或解释它们,以便他们了解为什么这种方法是最好的。
    【解决方案2】:

    尝试使用否定的lookahead (?! 断言模式server_name{[^}]+}) 不再出现。

    server_name{[^}]+}(?!.*server_name{[^}]+})

    那会匹配

    • server_name 字面匹配
    • {[^}]+} 匹配{,不匹配} 一次或多次并匹配}。例如匹配{abc.com; random text;}
    • (?! 否定前瞻,断言右侧的内容
      • .*server_name{[^}]+} 匹配任意字符零次或多次,然后匹配您的模式
    • ) 关闭前瞻

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-27
      相关资源
      最近更新 更多