【问题标题】:capture optional substring捕获可选子字符串
【发布时间】:2014-09-23 14:56:11
【问题描述】:

我正在尝试匹配这些行:

X=1 a b c Y=5 a bb aa
X=2 aa ccc d
X=3 ccc Y=9 d ee ff

“Y=x”子字符串是可选的。它可能存在于一行中,也可能不存在。 我想在第 1 组中捕获 X=x,在可选第 2 组中捕获 Y=x。

我正在使用这个正则表达式:

^(X=[0-9]+?).+?(Y=[0-9]+?)?.+?$

整行都匹配,但我只捕获第一组。即使存在可选子字符串,也永远不会捕获第二组。问题是 X= 和 Y= 之间可能有很多不同的词(也有 '=' 字符)。

任何想法如何捕获可选的第 2 组?

实际示例:http://regex101.com/r/rD4sO4/1

【问题讨论】:

    标签: regex optional capture regex-group


    【解决方案1】:

    更新

    这是一个更高效、更简洁的选择(不需要交替):

    ^(X=[0-9]+)(?:.+?(Y=[0-9]+))?.+?$
    

    Demo

    请注意,我从 [0-9] 中删除了惰性重复,因为无论如何匹配太多字符都不会有任何问题。


    说明

    原始表达式不起作用,因为正则表达式从左到右匹配(并且由于您使用的是惰性重复,我假设您理解正则表达式“贪婪”的概念)。因此,即使您的中间 .+? 很懒惰,Y=[0-9]+ 也是可选的,因此它可以一直匹配到尾随/必需的 .+?$。这可能不是人们所期望的,因为有一个懒惰的重复......但是当你总是可以回溯并尝试再次匹配它时,为什么要停下来寻找一个可选的片段。

    我的工作是因为我让中间 .+? 仅在 Y=[0-9]+ 存在时才存在。所以Y=[0-9]+ 总是被检查,但如果没有找到那没关系,因为整个组仍然是可选的。然后我们仍然可以以.+?$结尾。


    原创

    我绞尽脑汁想要一个更简洁的答案,但我使用了交替来让正则表达式引擎在匹配所有内容之前总是检查Y=[0-9]+?

    ^(X=[0-9]+)(?:.+?(Y=[0-9]+).+?|.+?)$
    

    Demo

    【讨论】:

    • 效果很好,谢谢。虽然我不知道具体是怎么回事。
    • 是的,谢谢@Sam。我需要阅读更多关于惰性重复的内容。
    • @Tmk 这里是repetition 的一些读物,其中包括关于懒惰与贪婪的部分:)
    【解决方案2】:

    或者这个模式

    (X=\d+)(?>[^Y\r\n]+|Y(?!=\d+))*(Y=\d+)?  
    

    Demo

    【讨论】:

      【解决方案3】:
      (X=\d+)|(Y=\d+)
      

      试试这个。查看演示。

      http://regex101.com/r/lS5tT3/21

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-16
        • 1970-01-01
        相关资源
        最近更新 更多