所以我得到了以下输入:1,6-10,10000,2,10-11
以下正则表达式:.NET正则表达式中的^\d+(?:,(\d+|\d+-\d+))*$
我想匹配逗号之间的每个组,但我也希望捕获组最终如下:
Group 1: 1
Group 2: 6-10
Group 3: 10000
Group 4: 2
Group 5: 10-11
我尝试过使用任何非捕获组和其他捕获组的组合,但我无法找到解决方案。我错过了什么?
答案 0 :(得分:2)
.net正则表达式实现提供了存储重复捕获组的子串的可能性。因此,使用此模式描述整个字符串:
\A(?:(\d+(?:-\d+)?)(?:,|\z))+\z
(其中\A
和\z
代表字符串的开头和结尾)您只需一次匹配即可获取捕获组1中的所有值:{{ 3}}
这样可以确保整个字符串从开头到结尾的格式正确。
代码示例:
string input = "1,6-10,10000,2,10-11";
string pattern = @"\A(?:(\d+(?:-\d+)?)(?:,|\z))+\z";
Match match = Regex.Match(input, pattern);
if (match.Success) {
Console.WriteLine("Matched text: {0}", match.Value);
for (int ctr = 1; ctr < match.Groups.Count; ctr++) {
Console.WriteLine(" Group {0}: {1}", ctr, match.Groups[ctr].Value);
int captureCtr = 0;
foreach (Capture capture in match.Groups[ctr].Captures) {
Console.WriteLine(" Capture {0}: {1}", captureCtr, capture.Value);
captureCtr++;
}
}
}
另一种方法是使用全局研究(几次连续匹配)并确保所有结果都是连续的。为此,您需要使用\G
锚点构建一个模式,该模式匹配上一个匹配后位置字符串的开头:demo
\G(\d+(?:-\d+)?)(?:(,)|\z)
为确保已达到字符串的结尾,您只需检查第二个捕获组在上一次匹配时是否为空。
代码示例:
string input = "1,6-10,10000,2,10-11";
string pattern = @"\G(\d+(?:-\d+)?)(?:(,)|\z)";
MatchCollection results = Regex.Matches(input, pattern);
if (results.Count == 0) {
Console.WriteLine("No results");
} else if ( results[results.Count - 1].Groups[2].Length > 0 ) {
Console.WriteLine("Bad format");
} else {
foreach (Match match in results) {
Console.WriteLine(match.Groups[1]);
}
}
显然,如果你已经知道你的字符串格式正确,这两种方法都是无用的,只需用逗号进行简单的拆分即可获得结果。