c# - 正则表达式匹配包含特定字符的最里面的括号集
问题描述
什么是正则表达式来获取包含特定字符的最里面的括号集;'|' 在这种情况下?
一些示例和(c#)测试方法:
string[] tests = {
"x () y", "",
"x (a) y", "",
"x (a.b()) y", "",
"x ((a).b() | (b).c()) y", "(a).b() | (b).c()",
"x (a|b) y", "a|b",
"x ((a|b) | c)", "a|b",
"x (a|b|c) y", "a|b|c",
"x (a|a.b()|c) y", "a|a.b()|c",
"x (a.b()|b.c()) y", "a.b()|b.c()",
"x (a.b()|b.c()|c) y", "a.b()|b.c()|c",
"x (a|b.c()|c.d()) y", "a|b.c()|c.d()",
"x (a|(b.c()|d)) y", "b.c()|d",
"x (a|a.b(a)|c) y", "a|a.b(a)|c"
};
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]));
}
解决方案
解决所有测试的“非常简单”的正则表达式:
var re = new Regex(@"
(?:\()
(
(?>
(?:
(?<p>\() |
(?<-p>\)) |
[^()|]+ |
(?(p)(?!))(?<pipe>\|)
)*
)
)
(?:\))
(?(p)(?!))
(?(pipe)|(?!))", RegexOptions.IgnorePatternWhitespace);
string result = match.Groups[1].Value;
注意使用RegexOptions.IgnorePatternWhitespace
. 正则表达式基于平衡组。基于你不应该尝试使用你不完全理解的正则表达式这一事实,我将省略关于它如何工作的确切解释。我只会说检查(?(pipe)|(?!))
检查是否至少 a|
在捕获中被捕获,而(?(p)(?!))
意味着“没有仍然被(?<p>\()
表达式捕获的开括号”。
我对这个正则表达式的看法是,它在正则表达式中是一种徒劳且危险的练习!(如果不清楚我属于某些人,当遇到问题时,会想“我知道,我会使用正则表达式”现在他们有两个问题。学派)。你不应该使用它。这是不可调试的代码恐怖。
附加的事情:这个正则表达式大量回溯......添加(?>
......)
以禁用回溯。
回溯的附加测试(第一个带有不平衡括号):
"((((amusemen).emoadj().cap()(, (are we |arent we|I gather)|)?)", "are we |arent we|I gather",
"((amusemen).emoadj().cap()(, (are we |arent we|I gather)|)?)", "are we |arent we|I gather",
推荐阅读
- node.js - 未捕获(承诺)错误:在 XMLHttpRequest.handleError (xhr.js:99) 的 createError (createError.js:16) 处出现网络错误
- spring-boot - OpenAPI 生成的 Spring Boot 服务器不验证所需的属性
- sql - 如何在标准 sql 中使用 json_extract 来获取值
- react-native - 如何在 React 本机 Drawer.Navigator 中添加注销按钮?
- javascript - 使用 Sheet.js 包导出时,如何将 CSV 中的所有单元格格式化为文本?
- c# - C#弹跳立方体游戏,从中心100px移除立方体
- firebase - React Native Pdf 未显示
- php - 如何在 foreach 循环中调用不同的多语言国家列表?
- linux - 无法在 Rocky 8.4 上从源代码构建 DSC (v1.2.1-0)/OMI (1.6.8-1)
- reactjs - 我应该在 redux 工具包中的哪里设置 localStorage