Обратитесь к той же ветке предыдущей альтернативной группы - PullRequest
1 голос
/ 30 марта 2020

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

12-34 # match: (1) (2) (3) (4)
1a-2b # match: (1) (a) (2) (b)
12-3b # nomatch

В двух словах: если первая часть имеет две цифры, то вторая часть также должна иметь две цифры. И если оно имеет букву, то вторая часть также должна иметь букву.

В PCRE-аромате (\d)(\d|[abc])-(\d)(\d|[abc]) соответствует третьей строке, так что это слишком допустимо.

Использование именованных групп , (\d)(?<named>\d|[abc])-(\d)(?P=named) не соответствует ни одной строке, поскольку для этого требуется, чтобы вторые символы были точно такими же. Это слишком ограничительно.

Могу ли я потребовать, чтобы моя вторая альтернативная группа (\d|[abc]) занимала ту же ветвь, что и первая (\d|[abc])?
Или мне нужно вернуться к полной (?:(\d)(\d)-(\d)(\d)|(\d)([abc])-(\d)([abc])) что дублирует части моего регулярного выражения?

1 Ответ

2 голосов
/ 30 марта 2020

В PCRE вы можете использовать это регулярное выражение:

^(?:(?<num>\d{2})-(?&num)|(?<alnum>\d\pL)-(?&alnum))$

Демонстрация RegEx 1

Подробности RegEx:

  • (?<num>\d{2}): именованная группа num для сопоставления 2 цифр
  • (?<alnum>\d\pL): именованная группа alnum для сопоставления 1 ди git, за которой следует буква
  • (?&num): Сопоставить тот же подшаблон как в именованной группе num
  • (?&alnum): сопоставить тот же подшаблон как в названной группе alnum

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

^(?:(?<num>\d{2})|\d\pL)-(?(num)\d{2}|\d\pL)$

RegEx Demo 2

...