正则表达式-重叠的命名捕获组

本文关键字:重叠 正则表达式 | 更新日期: 2023-09-27 17:54:10

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

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

5, 5
3
2, 5

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

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

我想这个问题的简化是:有可能在多个捕捉组中包含同一个角色吗?我目前正在使用C#,但很想知道这在其他语言中是否也可行。

正则表达式-重叠的命名捕获组

我不认为这在的每个情况下都是可能的,但这里有几个技巧可以用于您的示例:

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

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

如果只有一个数字,(?:'k<firstValue>, *)?不消耗任何东西,这是可以的,因为它是可选的。这使得匹配位置仍然在字符串的开头,因此(?<secondValue>'d+)再次捕获第一个数字,这次是在组secondValue中。我们还没有尝试在firstValue组中加入任何其他内容,所以这个数字仍然存在。

这里有另一种不那么优雅但可能更容易理解的方法:

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

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

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

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;
    }
  );

是否可以在多个捕获中包含同一个角色组

直接回答-(除非您有嵌套的捕获组,否则不会(。一旦角色被捕获或匹配,就不能再进行匹配。

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

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

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