C#Regex.Match大括号 - 仅限内容?(不包括牙箍)

Pet*_*erX 20 .net c# regex

我一直无法找到答案:我可以使用该Regex.Matches方法仅返回带花括号的项目的内容吗?

如果我使用正则表达式,({[^}]*})我的MatchCollection值包括括号.我想匹配,但只返回内容.这是我到目前为止所拥有的:

Regex regex = new Regex(({[^}]*}), RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches("Test {Token1} {Token 2}");
// Results include braces (undesirable)
var results = matches.Cast<Match>().Select(m => m.Value).Distinct().ToList();
Run Code Online (Sandbox Code Playgroud)

Mil*_*ski 26

我总是很喜欢它.所以你可以使用"积极的lookbehind"(?<= ...)和"积极的向前看"(?= ...)组:

(?<=\{)
[^}]*
(?=\})
Run Code Online (Sandbox Code Playgroud)

意思是:

  • 需要比赛打开大括号
  • 收集文本(当然) - 在我可能[^ {}]*之前评论
  • 要求比赛关闭花括号

  • 是的,所以完整的`(?<=\{)[^}]*(?= \})`正则表达式似乎运行良好.谢谢. (6认同)

Wik*_*żew 11

在C#中,正如在许多其他的编程语言,正则表达式引擎支持捕获组,是子匹配,匹配整个正则表达式模式的子字符串的部分,在正则表达式模式定义带括号的帮助下(如1([0-9])3将匹配123和保存价值2进入捕获组1缓冲区).通过Match.Groups[n].Value其中n是模式内捕获组的索引来访问捕获的文本.

捕捉是更有效的外观.只要不需要复杂的条件,捕获组就是更好的选择.

看看我在regexhero.net上执行的正则表达速度测试:

在此输入图像描述

现在,我们如何才能获得花括号内的子串

  • 如果里面没有其他花括号,带有否定的字符类:{([^{}]*)
  • 如果可以嵌套花括号: {((?>[^{}]+|{(?<c>)|}(?<-c>))*(?(c)(?!)))

在这两种情况下,我们匹配一个开口{,然后匹配(1)除{or 之外的任何字符},或者(2)任何字符直到第一个配对}.

这是示例代码:

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));
Run Code Online (Sandbox Code Playgroud)

结果:Token1, Token 2,Token1, Token {2}.

请注意,RegexOptions.IgnoreCase如果没有可以在模式中具有不同大小写的文字字母,则这是多余的.


bun*_*eeb 5

感谢Milosz Krajewski,没有什么可以补充,但这里是功能

private List<String> GetTokens(String str)
{
    Regex regex = new Regex(@"(?<=\{)[^}]*(?=\})", RegexOptions.IgnoreCase);
    MatchCollection matches = regex.Matches(str);

    // Results include braces (undesirable)
    return matches.Cast<Match>().Select(m => m.Value).Distinct().ToList();
}
Run Code Online (Sandbox Code Playgroud)