22

我一直无法找到答案:我可以使用该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();
4

7 回答 7

31

我一直很喜欢它。因此,您可以使用“正向后视”(?<=...) 和“正向前瞻”(?=...) 组:

(?<=\{)
[^}]*
(?=\})

意思是:

  • 需要在匹配打开大括号
  • 收集文本(当然) - 正如我之前评论的那样,我也可能是 [^{}]*
  • 匹配需要关闭大括号
于 2013-05-14T08:13:23.550 回答
14

在 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当您没有可以在模式中具有不同大小写的文字字母时,这是多余的。

于 2015-11-26T10:52:10.653 回答
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();
}
于 2014-01-13T09:59:25.820 回答
3

只需将大括号移到括号外:

 {([^}]*)}
于 2013-05-14T08:00:21.270 回答
1

它是 C# .net 的正则表达式。

@"{(.*?)}"

它显示一个

令牌1 令牌2

于 2014-08-14T12:39:05.057 回答
1

稍微修改@Milosz Krajewski 的答案

(?<=\{)[^}{]*(?=\})

这将跳过字符串中的中间单个打开和关闭花括号。

于 2019-02-01T07:52:04.123 回答
0

如果我明白你想要什么。将正则表达式更改为{([^}]*)}. 这只会捕获 {} 之间的文本,而不包括它们。

于 2013-05-14T08:01:16.260 回答