Сопоставление групп вложенных скобок с использованием Regex и Pushdown-Automata

Я работаю над регулярным выражением С#, которое может соответствовать вложенным конструкциям (круглые скобки в данном случае), а также произвольным операторам (символ '|' в этом случае).

Я начал с использования выталкивающих автоматов, как описано здесь.

Что у меня есть до сих пор:

String pattern = @"
(?# line 01) \(
(?# line 02) (?>
(?# line 03) \( (?<DEPTH>)
(?# line 04) |
(?# line 05) \) (?<-DEPTH>)
(?# line 06) |
(?# line 07) .?
(?# line 08) )*
(?# line 09) (?(DEPTH)(?!))
(?# line 10) \)
";

var source = "((Name1| Name2) Blah) | (Name3 ( Blah | Blah))";

var matches = Regex.Matches(source, pattern,
  RegexOptions.IgnorePatternWhitespace);
matches.Dump();

Дает следующие результаты:

// ((Name1| Name2) Blah)
// (Name3 ( Blah | Blah))

Желаемые результаты:

// ((Name1| Name2) Blah)
// |
// (Name3 ( Blah | Blah))

Примечание. Между группами могут быть или не быть операторы. Например, источник может выглядеть так: "((Имя1|Имя2) Бла) (Имя3 (Бла | Бла))"


person Tim Capps    schedule 19.06.2013    source источник
comment
Regex не является хорошим кандидатом для этого. Я бы предложил разобрать его самостоятельно или использовать библиотеку синтаксического анализа. То есть, предполагая, что ваша вложенная структура скобок может быть более сложной, чем то, что вы дали.   -  person Simon Whitehead    schedule 20.06.2013
comment
@SimonWhitehead Да, я знаю, что синтаксический анализатор - лучший способ обеспечить ремонтопригодность. Я планирую использовать Antlr для более постоянного решения. Спасибо за ваш вклад!   -  person Tim Capps    schedule 20.06.2013


Ответы (1)


Вы можете попробовать это: (просто добавив |\| в конце)

\((?>\((?<DEPTH>)|\)(?<-DEPTH>)|.?)*(?(DEPTH)(?!))\)|\|
person Casimir et Hippolyte    schedule 19.06.2013