【问题标题】:Regular expressions - overlapping named capture groups正则表达式 - 重叠命名捕获组
【发布时间】:2013-01-18 17:13:16
【问题描述】:

是否可以编写正则表达式将单个数字捕获为 2 个不同的命名捕获组?

例如,如果我正在捕获一对值,但有时只有一个值:

5, 5
3
2, 5

我想将单个值存储为第一个和第二个捕获组,这可能吗?例如。如果我的组被命名为 firstValue 和 secondValue:

firstValue = 5, secondValue = 5
firstValue = 3, secondValue = 3
firstValue = 2, secondValue = 5

我想这个问题的简化是:是否可以在多个捕获组中包含相同的字符?我目前正在使用 C#,但很想知道这是否也可以在其他语言中使用。

【问题讨论】:

    标签: c# regex


    【解决方案1】:

    我不认为在每一个情况下都有可能,但这里有一些技巧可以用于你的例子:

    @"(?m)^(?=(?<firstValue>\d+\b))(?:\k<firstValue>, *)?(?<secondValue>\d+)\r?$"
    

    第一个数字在组firstValue 中被捕获,但由于该组在前瞻内,匹配位置随后返回到字符串的开头。如果有第二个数字,第一个数字将紧跟逗号。 (?:\k&lt;firstValue&gt;, *)? 尝试使用数字、逗号和任何尾随空格,(?&lt;secondValue&gt;\d+) 捕获第二个数字。

    如果只有一个数字,(?:\k&lt;firstValue&gt;, *)? 不会消耗任何内容,这没关系,因为它是可选的。这使得匹配位置仍然在字符串的开头,所以(?&lt;secondValue&gt;\d+) 再次捕获第一个数字,这次是在组secondValue 中。我们还没有尝试在firstValue 组中添加任何其他内容,因此该号码仍然存在。

    这是另一种不太优雅但可能更容易理解的方法:

    @"(?m)^(?<secondValue>(?<firstValue>\d+))(?:, *(?<secondValue>\d+))?\r?$"
    

    与其他响应者的解决方案基本相同,但我从捕获 both 组中的第一个数字开始。如果证明有第二个数字,它将在组secondValue 中捕获,覆盖已经存在的值。组firstValue 仍然包含第一个数字。

    【讨论】:

    • 好的,太好了。因此,总而言之,我可以使用嵌套捕获组(第二个示例)或正向前瞻结合对现有捕获组的反向引用(第一个示例)。顺便说一句, \r 足以匹配换行符吗? [\r\n]* 会更好吗?
    • 实际上,\r? 是针对 .NET 正则表达式风格缺陷的一种解决方法。 $ 应该匹配字符串的最末端或行分隔符之前,如 here 所述。实际上,您可能会看到的唯一行分隔符是 \r\n\n。 (\r 单独被旧的 Apple 操作系统使用,而其他我从未见过的操作系统。)然而,.NET 甚至没有走那么远。它识别的唯一行分隔符是 \n 单独。因此,在 .NET 正则表达式中使用 \r?$ 而不是 $ 已成为常见做法。
    • 这已确认有效(我采用了第二种方法)。谢谢!
    【解决方案2】:

    不,你不能这样做。相反,你可以检查你是否捕获了第二个值。

    var values=Regex.Matches(@"(?<fv>\d+)(,\s*(?<sv>\d+))?")
      .Cast<match>()
      .Select(m=>
        new {
          firstValue=m.Groups["fv"].Value;
          secondValue=m.Groups["sv"].Value==""?m.Groups["fv"].Value:m.Groups["sv"].Value;
        }
      );
    

    【讨论】:

      【解决方案3】:

      是否可以在多个捕获中包含相同的字符 组?

      直接回答 - (除非您有嵌套的捕获组,否则不会)。字符一旦被捕获或匹配,就不能再匹配了。

      但是,如果您的问题有时是单个值,那么您可以使用 ? 量词将第二个捕获组设为可选。

      (?<firstValue>\d+)(, (?<secondValue>\d+))?
      

      所以现在我们将, secondValue 设为可选。所以它将匹配3, 53

      【讨论】:

      • 如果是我,我会回答“直接回答 - 是的,但前提是您使用嵌套捕获组。”我认为最初的 No 具有误导性。
      猜你喜欢
      • 2019-03-17
      • 2011-03-03
      • 1970-01-01
      • 2019-05-19
      • 1970-01-01
      • 2014-11-13
      • 2017-09-13
      • 2011-03-11
      • 2017-01-07
      相关资源
      最近更新 更多