在 C# 中,与许多其他编程语言一样,正则表达式引擎支持捕获组,即子匹配,匹配整个正则表达式模式的子字符串的一部分,在括号的帮助下在正则表达式模式中定义(例如,1([0-9])3
将匹配123
并保存2
到捕获组 1 缓冲区)。通过Match.Groups[n].Value
其中n是模式内捕获组的索引来访问捕获的文本。
捕获比环视要有效得多。只要不需要复杂的条件,捕获组就是更好的选择。
查看我在 regexhero.net 上执行的正则表达式速度测试:
现在,我们怎样才能得到花括号内的子字符串?
- 如果里面没有其他花括号,则带有否定字符类:
{([^{}]*)
- 如果可以嵌套大括号:
{((?>[^{}]+|{(?<c>)|}(?<-c>))*(?(c)(?!)))
在这两种情况下,我们匹配一个开头{
,然后匹配(1)除{
or之外的任何字符}
,或(2)直到第一个 pair 的任何字符}
。
这是示例代码:
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
当您没有可以在模式中具有不同大小写的文字字母时,这是多余的。