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

时间:2013-01-18 17:13:17

标签: c# regex

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

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

5, 5
3
2, 5

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

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

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

3 个答案:

答案 0 :(得分:2)

我不认为每个案例都有可能,但这里有一些你可以用来举例的技巧:

@"(?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仍包含第一个数字。

答案 1 :(得分:0)

  

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

直接回答 - (除非你有嵌套的捕获组)。一旦角色被捕获或匹配,就无法再次匹配。

但是,如果您的问题有时会出现单个值,那么您可以使用?量词来使第二个捕获组成为可选项。

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

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

答案 2 :(得分:0)

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

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