2016-08-02 3 views
1

я эти строки кода для взятия операторов в круглых скобках:C# регулярное выражение для сопоставления sepcific текст внутри вложенных скобок

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 

Это дает мне этот результат: ИЛИ ИЛИ

Но, когда мой вклад имеет более чем вложенные скобки, он работает неправильно.

Для этого входа:

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

Я хочу взять за результат ИЛИ ИЛИ, но он печатает ИЛИ И ИЛИ.

Хотя в строке есть два знака (, когда он завершает обработку после согласования первого символа ).

Как настроить шаблон регулярного выражения?

+1

Вы не должны использовать регулярные выражения для иерархий (код, XML и др) – MickyD

+0

Смотрите также https://stackoverflow.com/questions/19596502/regex-nested-parentheses. –

+0

Тот, который использовался для закрытия этого вопроса, не является полным дубликатом, хотя он объясняет концепцию и обеспечивает почти точное решение. –

ответ

2

Вашего \(.*?\) регулярного выражение содержит 3 части: 1) \( соответствия буквального (, 2) .*?ленивых шаблона согласования точек (что соответствует 0+, кроме символа новой строки любых символов, как можно, вплоть до первой ), и 3) a \), соответствующие буквам ).

Используйте balancing construct, если ваши строки не избежали последовательности:

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

Дело в том, что выражение не должно быть заключено с любыми анкеров (как в What are regular expression Balancing Groups).

Детали:

  • \( - буквальный (
  • (?> - начало атомной группы для предотвращения возвратов в него
    • [^()] - любой символ, кроме ( и )
    • | - или
    • (?<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

+0

Он решает мою проблему. Спасибо за ваш интерес. –

+0

Если вы хотите удалить вопрос, сообщите мне, я удалю свой ответ. –

+0

Я хочу остаться на этот вопрос. Потому что, я новичок для C#, и я не мог решить эту проблему, хотя для исследования в этой теме. Ваш ответ может помочь другим людям, таким как я. Еще раз спасибо .. –