用于匹配嵌套括号内的特定文本的 C# 正则表达式
我有这些代码行用于括号之间的运算符:
I have these code lines for take to operators between parentheses:
string filtered = Regex.Replace(input, "\\(.*?\\)", string.Empty);
var result = filtered.Split(new[] { ' ' },
StringSplitOptions.RemoveEmptyEntries)
.Where(element => element == "OR" || element == "AND");
string temp = string.Join(" ", result);
这些行不适用于嵌套括号.
These lines do not work for nested parentheses.
例如;它适用于此输入:
X1 OR ( X2 AND X3 AND X4 AND X5 ) OR X6
它给了我这个结果:OR OR
但是,当我的输入有多个嵌套括号时,它会出错.
But, when my input has more than one nested parentheses, it works wrongly.
对于这个输入:
X1 OR ( X2 AND( X3 AND X4 ) AND X5 ) OR X6
我想取结果 OR OR 但它打印 OR AND OR.
I want to take for result OR OR but it prints OR AND OR.
虽然字符串中有两个(
字符,但匹配第一个)
字符后结束处理.
Although there are two (
characters in string, when it ends processing after matching the first )
character.
如何调整我的正则表达式模式?
How can I adjust my regex pattern?
你的 \(.*?\)
正则表达式包含 3 个部分:1) \(
匹配一个文字 (
, 2) .*?
lazy 点匹配模式(匹配 0+ 除换行符以外的任何字符,尽可能少,直到 first )
和 3) 匹配文字 )
的 \)
.
Your \(.*?\)
regex contains 3 parts: 1) \(
matching a literal (
, 2) .*?
lazy dot matching pattern (that matches 0+ any characters other than a newline, as few as possible, up to the first )
, and 3) a \)
matching a literal )
.
使用平衡结构 如果您字符串不能有转义序列:
@"\((?>[^()]|(?<o>)\(|(?<-o>)\))*\)(?(o)(?!))"
这里的重点是表达式不应包含任何锚点(如 什么是正则表达式平衡组).
The point here is that the expression should not be enclosed with any anchors (as in What are regular expression Balancing Groups).
详情:
-
\(
- 文字(
-
(?>
- 原子组的开始以防止回溯到它-
[^()]
- 除了(
和)
之外的任何字符 -
|
- 或 -
(?<o>)\(
- 匹配文字(
并将空值压入堆栈 "o" -
|
- 或 -
(?<-o>)\)
- 匹配文字)
并从堆栈 "o" 中删除一个值
-
\(
- a literal(
-
(?>
- start of an atomic group to prevent backtracking into it-
[^()]
- any char other than(
and)
-
|
- or -
(?<o>)\(
- matches a literal(
and pushes an empty value into stack "o" -
|
- or -
(?<-o>)\)
- matches a literal)
and removes one value from stack "o"
见正则表达式演示.
var input = "X1 OR ( X2 AND( X3 AND X4 ) AND X5 ) OR X6"; var filtered = Regex.Replace(input, @"\((?>[^()]|(?<o>)\(|(?<-o>)\))*\)(?(o)(?!))", string.Empty); var result = filtered.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) .Where(element => element == "OR" || element == "AND"); var temp = string.Join(" ", result);
参见 C# 演示
-
-