Регекс и балансирующие группы

Я застрял на регулярное выражение:

У меня есть строка ввода с цифрами и одной буквой, которая может содержать больше цифр и букв внутри строки и между скобками:

Всего несколько примеров

26U(35O40) will be read as 26 and (35 or 40)
22X(34U(42O27)) will be read as 22 xor (34 and (42 or 27))
21O(24U27) will be read as 21 or (24 and 27)
20X10X15 Will be read as 20 xor 10 xor 15

Я читал, что это может быть получено с помощью балансировочных групп, однако я пробовал много регулярных выражений, а закрытие следующее:

(?<ConditionId>\d+)(?<Operator>X|U|O)?(?<Open>\()(?<ConditionId>\d+)+(?<Operator>X|U|O)?(?<ConditionId>\d+)(?<-Open>\))

Я также подумал, что, возможно, я усложняю задачу, и мне нужно просто запустить несколько раз одно и то же регулярное выражение, первый раз для всего, что находится за скобками, и второй раз для внутреннего содержимого и запустить его снова, когда совпадает с внутренним. Что-то вроде того:

(?<ConditionId>\d+)?(?<Operator>U|O|X)?(?<Inner>(?:\().*(?:\)))

Предложения или помощь?

Заранее спасибо.

Редактировать 1: мне не нужно проверять ввод, просто разобрать его.

Редактировать 2: Итак, причина в том, чтобы идентифицировать условие по условию Id, а затем применить оператор к другим условиям во входной строке. В том же порядке, что и во входной строке, более общим примером, облегчающим понимание, будут логические элементы:

Для заданного ввода 20x10x15 мне придется идентифицировать условия по условию ID и проверить, является ли условие допустимым, и применить к ним оператор XOR, что-то вроде:

true X true X false = false;
false X false X true = true;
true X (false U true) = true

По этой причине я не могу сгруппировать все в группу "ConditionId" и "Operator".

Редактировать 3 Это также правильный пример

(23X10)U(30O(20X19)

2 ответа

Если вы используете (\d+[A-Z]*[()]?)+ он вернет один матч на 22X(34U(42O27)) с этими захватами на Groups[1].Captures

22X(34U(42Oа также27)

Это дает достаточно информации для обработки кода.

На 20X10X15 та же самая группа захвата дает

20X10X а также 15

Предполагая, что ваши входные данные уже действительны, и вы хотите проанализировать их, вот довольно простое регулярное выражение для достижения этой цели:

(?:
    (?<ConditionId>\d+)
    |
    (?<Operator>[XUO])
    |
    (?<Open>\()
    |
    (?<Group-Open>\))
)+

Рабочий пример - Regex Storm - переключитесь на вкладку таблицы, чтобы увидеть все захваты.

Шаблон захватывает:

  • Числа в $ConditionId группа.
  • Операторы в $Operator группа.
  • Подвыражения в скобках в $Group группа (нужно лучшее имя?). Например, для строки 22X(34U(42O27)), у него будет два захвата: 42O27 а также 34U(42O27),

Каждый захват содержит позицию строки совпадений. Отношения между $Group и его содержали $Operators, $ConditionIdс и суб-$Groups выражается только с использованием этих позиций.

(?<Group-Open>) синтаксис используется, когда мы достигаем закрывающей скобки, чтобы захватить все, начиная с соответствующей открывающей скобки. Это объясняется более подробно здесь: Что такое группы балансировки регулярных выражений?

Другие вопросы по тегам