.NET 在其 RegularExpression 实现中提供了一个 Capture 集合,因此您可以获得给定重复组的所有实例,而不仅仅是它的最后一个实例。太好了,但是我有一个带有子组的重复组,我正在尝试获取子组,因为它们在组下是相关的,但找不到方法。有什么建议么?
我查看了许多其他问题,例如:
但我没有找到任何适用的答案,无论是肯定的(“是的,这就是方法”)或否定的(“不,做不到。”)。
对于一个人为的例子说我有一个输入字符串:
abc d x 1 2 x 3 x 5 6 e fgh
其中“abc”和“fgh”表示我想在较大文档中忽略的文本,“d”和“e”包裹感兴趣区域,在该感兴趣区域内,“xn [n]”可以重复任何次数。我感兴趣的是“x”区域中的那些数字对。
所以我使用这个正则表达式模式解析它:
.*d (?<x>x ((?<fir>\d+) )?((?<sec>\d+) )?)*?e.*
这将在文档中找到一个匹配项,但会多次捕获“x”组。这是我要在此示例中提取的三对:
- 1, 2
- 3
- 5、6
但我怎样才能得到它们?我可以执行以下操作(在 C# 中):
using System;
using System.Text;
using System.Text.RegularExpressions;
string input = "abc d x 1 2 x 3 x 5 6 e fgh";
string pattern = @".*d (?<x>x ((?<fir>\d+) )?((?<sec>\d+) )?)*?e.*";
foreach (var x in Regex.Match(input, pattern).Groups["x"].Captures) {
MessageBox.Show(x.ToString());
}
因为我引用组“x”,所以我得到了这些字符串:
- × 1 2
- × 3
- × 5 6
但这并没有让我明白数字本身。所以我可以独立地做“fir”和“sec”而不仅仅是“x”:
using System;
using System.Text;
using System.Text.RegularExpressions;
string input = "abc d x 1 2 x 3 x 5 6 e fgh";
string pattern = @".*d (?<x>x ((?<fir>\d+) )?((?<sec>\d+) )?)*?e.*";
Match m = Regex.Match(input, pattern);
foreach (var f in m.Groups["fir"].Captures) {
MessageBox.Show(f.ToString());
}
foreach (var s in m.Groups["sec"].Captures) {
MessageBox.Show(s.ToString());
}
要得到:
- 1
- 3
- 5
- 2
- 6
但是我无法知道缺少“4”的是第二对,而不是其他对中的一对。
那么该怎么办?我知道我可以很容易地在 C# 中解析它,甚至可以在“x”组上进行第二次正则表达式测试,但是由于第一次 RegEx 运行已经完成了所有工作并且结果是已知的,似乎应该有一种方法操纵 Match 对象以从中获得我需要的东西。
请记住,这是一个人为的例子,现实世界的情况要复杂一些,所以只是在上面扔额外的 C# 代码会很痛苦。但是,如果现有的 .NET 对象无法做到这一点,那么我只需要知道这一点,我将继续前进。
想法?