C#正则表达式用于匹配嵌套括号内的单个文本

时间:2016-08-02 06:24:38

标签: c# regex nested 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);

这些行不适用于嵌套括号。

例如;它适用于输入

X1 OR ( X2 AND X3 AND X4 AND X5 ) OR X6

它给我这个结果: OR OR

但是,当我的输入有多个嵌套括号时,它会错误地工作。

对于此输入:

X1 OR ( X2 AND( X3 AND X4 ) AND X5 ) OR X6

我想取结果 OR OR ,但会打印 OR AND OR

虽然字符串中有两个(字符,但在匹配第一个)字符后结束处理时。

如何调整我的正则表达式?

1 个答案:

答案 0 :(得分:3)

您的\(正则表达式包含3个部分:1)(匹配文字.*?,2)) 懒惰点匹配模式(匹配0 +除换行符之外的任何字符,尽可能少,直到第一个 \),以及3)匹配文字)的{​​{1}}。

如果您的字符串无法转义序列,请使用balancing construct

@"\((?>[^()]|(?<o>)\(|(?<-o>)\))*\)(?(o)(?!))"

这里的要点是表达式不应该包含任何锚点(如What are regular expression Balancing Groups中所示)。

<强>详情:

  • \( - 文字(
  • (?> - 启动一个原子组以防止回溯到它
    • [^()] - ()
    • 以外的任何字符
    • | - 或
    • (?<o>)\( - 匹配文字(并将空值推入堆栈“o”
    • | - 或
    • (?<-o>)\) - 匹配文字)并从堆栈中移除一个值“o”
  • )* - 匹配零个或多个原子组
  • \) - 文字)
  • (?(o)(?!)) - 如果堆栈“o”包含值(不为空),则条件构造会使匹配失败。

请参阅regex demo

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# demo