用于否定字符类的 C# 正则表达式,除非字符彼此相邻

Posted

技术标签:

【中文标题】用于否定字符类的 C# 正则表达式,除非字符彼此相邻【英文标题】:C# regex for negated character class unless chars are next to one another 【发布时间】:2018-10-25 18:54:05 【问题描述】:

我需要匹配字符串中最里面的一组括号之间的字符,但允许使用空括号,例如“()”。尽我所能告诉我这里需要某种否定的前瞻(它与它被标记为重复的问题完全不同)

正确包含'()'的初始版本是:

var re = new Regex(@"\(([^()]+)\)");

一些测试示例:

x (a) y          -> a
x (a b) y        -> a b
x (a b c) y      -> a b c
x (a b() c) y    -> a b() c
x (a() b() c) y  -> a() b() c
x (a b() c()) y  -> a b() c()
x (a b(a) c) y   -> a
x (a (b() c)) y  -> b() c
x () y           -> empty

 

还有一个 c# 测试方法(适合您的断言库):

var re = new Regex(@"\(([^()]+)\)");

string[] tests = 
    "x (a) y", "a",
    "x (a b) y", "a b",
    "x (a b c) y", "a b c",
    "x (a b() c) y", "a b() c",
    "x (a() b() c) y", "a() b() c",
    "x (a b() c()) y", "a b() c()",
    "x (a b(a) c) y", "a",
    "x (a (b() c)) y", "b() c",
    "x () y", ""
;

for (int i = 0; i < tests.Length; i+=2)

    var match = re.Match(tests[i]);
    var result = match.Groups[1].Value;
    Assert.That(result, Is.EqualTo(tests[i + 1]));

【问题讨论】:

研究捕获组。一旦你掌握了这块拼图,你应该就能拼好剩下的了。 @wiktor-stribiżew 我想你可能在这里遗漏了一些东西。首先,您的正则表达式不是有效答案(请参阅测试用例)。其次,这是一个与您将其标记为重复的问题非常不同的问题。如何编辑问题以使其更清楚? 【参考方案1】:

你可以使用这样的东西:(不需要 Lookarounds)

\(((?:[^()]|\(\))+)\)

对正则表达式所做的调整:

在非捕获组中添加了[^()] 以及替代|\(\),以便它可以匹配任一() 以外的字符 strong> 空括号()

Try it online.

或者,您可以摆脱捕获组如果您不需要它,并使用这样的 Lookarounds 将您的匹配项放在完全匹配而不是组中:

(?<=\()(?:[^()]|\(\))+(?=\))

这样,您可以直接使用match.Value 而不是match.Groups[1].Value 访问您的匹配项。

Here's a demo.

如果有什么不清楚的地方请告诉我。

【讨论】:

很好 -- 另请参阅***.com/questions/50560112/…

以上是关于用于否定字符类的 C# 正则表达式,除非字符彼此相邻的主要内容,如果未能解决你的问题,请参考以下文章

否定正则表达式中的特定字符

正则表达式的否定

如何在 JavaScript 字符串替换中否定匹配正则表达式? [复制]

基本正则扩展正则

用于在 C# 中获取字符串中的数值的正则表达式

否定字符类中的单引号