在 C# 中,与许多其他编程语言一样,正则表达式引擎支持 捕获组,即 子匹配,匹配的子字符串的一部分一个完整的正则表达式模式,在括号的帮助下在正则表达式模式中定义(例如,1([0-9])3 将匹配 123 并将 2 的值保存到捕获组 1 缓冲区中)。捕获的文本通过Match.Groups[n].Value 访问,其中 n 是模式内捕获组的索引。
捕捉比环视更有效。只要不需要复杂的条件,捕获组就是更好的选择。
查看我在 regexhero.net 上执行的正则表达式速度测试:
现在,我们怎样才能得到花括号内的子字符串?
- 如果里面没有其他花括号,一个否定字符类:
{([^{}]*)
- 如果可以嵌套大括号:
{((?>[^{}]+|{(?<c>)|}(?<-c>))*(?(c)(?!)))
在这两种情况下,我们都会匹配开头的 {,然后匹配 (1) 除 { 或 } 之外的任何字符,或 (2) 直到第一对 } 之前的任何字符。
这里是sample code:
var matches = Regex.Matches("Test {Token1} {Token 2}", @"{([^{}]*)");
var results = matches.Cast<Match>().Select(m => m.Groups[1].Value).Distinct().ToList();
Console.WriteLine(String.Join(", ", results));
matches = Regex.Matches("Test {Token1} {Token {2}}", @"{((?>[^{}]+|{(?<c>)|}(?<-c>))*(?(c)(?!)))");
results = matches.Cast<Match>().Select(m => m.Groups[1].Value).Distinct().ToList();
Console.WriteLine(String.Join(", ", results));
结果:Token1, Token 2、Token1, Token {2}。
请注意,RegexOptions.IgnoreCase 是多余的,当您没有可以在模式中具有不同大小写的文字字母时。