1

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

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

5, 5
3
2, 5

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

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

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

4

3 回答 3

2

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

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

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

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

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

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

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

于 2013-01-19T13:58:26.430 回答
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;
    }
  );
于 2013-01-18T17:44:02.093 回答
0

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

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

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

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

所以现在我们已经, secondValue选择了。所以它会同时匹配3, 53

于 2013-01-18T17:15:13.210 回答