Имя условной группы регулярных выражений

Кажется, я не могу найти никакой информации об этом, поэтому я не уверен, возможно ли это или нет, но вот:

Есть ли способ иметь несколько вариантов имени соответствующей группы? Я получаю параметры из кода и использую имена групп регулярных выражений, чтобы использовать их впоследствии. Однако моя последовательность имеет несколько (очень похожих) форматов, и порядок параметров меняется. Следовательно, мой вопрос: может ли группа иметь другое имя, если другая группа не совпадает?

Пример: (?'type'A|B|C)-(?'length_or_diameter'\d+)(?:x(?'length'\d+))?

Форматы кода: (type)-(length) ИЛИ (type)-(diameter)x(length)

см. здесь

У меня есть способы обойти это в коде, но я думаю, что было бы намного элегантнее, если бы это можно было решить в самом регулярном выражении. Поэтому вот мой вопрос: есть ли способ назвать группу 2 (length_or_diameter) либо «длиной», если группа 3 не имеет совпадения, либо «диаметром», если у группы 3 есть совпадение, вместо того, чтобы называться length_or_diameter и требовать больше логика в коде?


person DMX David Cardinal    schedule 27.02.2019    source источник
comment
Вы можете использовать только одно имя для именованной группы захвата. В зависимости от механизма регулярных выражений вы можете легко обойти это с помощью группы сброса ветвей или нескольких групп с одинаковыми именами.   -  person Wiktor Stribiżew    schedule 27.02.2019
comment
Что такое длина и диаметр в A-5 и B-6x3? Какая у вас библиотека регулярных выражений? Попробуйте (?'type'A|B|C)-(?:(?'diameter'\d+)(?=x\d))?(?:x?(?'length'\d+))?   -  person Wiktor Stribiżew    schedule 27.02.2019
comment
@WiktorStribiżew Когда я экспериментирую с regex101, я не могу использовать несколько групп с одинаковыми именами. Это был один из вариантов, которые я пробовал, прежде чем публиковать это. Ваше второе решение действительно дает решение для конкретного примера, который у меня был. Я отмечу это как принятый ответ на данный момент.   -  person DMX David Cardinal    schedule 27.02.2019


Ответы (1)


Вы можете использовать только одно имя для именованной группы захвата и не можете изменить его динамически после создания шаблона.

Вы можете использовать группы с одинаковыми именами (если ваш движок регулярных выражений их поддерживает, например, Onigmo в Ruby, библиотеку регулярных выражений .NET или PCRE с включенной опцией J):

(?'type'A|B|C)-(?:(?'diameter'\d+)x(?'length'\d+)|(?'length'\d+))

См. демонстрацию regex101 PCRE. Вот вариант с группой сброса ветки, (?|...|...) :

(?'type'A|B|C)-(?|(?'diameter'\d+)x(?'length'\d+)|()(?'length'\d+))

См. демонстрацию регулярного выражения (однако не работает в .NET).

Другой обходной путь — поиграть с поисковыми решениями и необязательными группами:

(?'type'A|B|C)-(?:(?'diameter'\d+)x)?(?'length'\d+)?

См. другую демонстрацию регулярного выражения. Этот соответствует

  • (?'type'A|B|C) - A, B или C в группе "тип"
  • - - a -
  • (?:(?'diameter'\d+)x)? - an optional non-capturing group matching
    • (?'diameter'\d+) - 1 or more digits in Group diameter
    • x - x символ
  • (?'length'\d+)? - необязательная длина группы захвата, 1+ цифры.
person Wiktor Stribiżew    schedule 27.02.2019