Небольшое дополнение и исправление к аккуратному ответу Аллана:
3-й шаблон не соответствует должным образом в обработчике регулярных выражений .NET, поскольку обратная ссылка \2
должна быть пронумерована иначе, чем в показанном шаблоне PCRE (с использованием regex101).
Вместо \2
оно должно быть \1
:
^(?<pool>([A-Z])\1{0,2})(?<number>(100|[1-9]\d?))$
Этот dotnetfiddle демонстрирует проблему: вместо ~ 300 тестовых случаев я создал только первые 100 (из A1-A100).
Вы можете проверить это самостоятельно, используя regexstorm , тестер регулярных выражений .NET.
Почему? Существует небольшая разница между тем, как именованные группы захвата, смешанные с обычными группами захвата, упоминаются в .NET regex и PCRE, например, в PHP.
С первого взгляда работает так же:
Захваты с круглыми скобками автоматически нумеруются слева направо
право на основе порядка открывающих скобок в регулярном
выражение, начиная с одного **. Захват, который нумеруется как
текст соответствует шаблону регулярного выражения.
Ref. MSDN: группировка конструкций в регулярных выражениях
Итак, пока
большинство вкусовых номеров как именованных, так и неназванных групп захвата
считая их открывающие скобки слева направо. Добавление именованного
захват группы в существующее регулярное выражение по-прежнему расстраивает числа
неназванные группы
В .NET, однако,
неназванные группы захвата
сначала назначенные номера, считая их открывающие скобки слева
направо, пропуская все названные группы. После этого именованные группы
присваивают числа, которые следуют, считая открывающие скобки
названных групп слева направо.
На самом деле это объясняется на той же странице регулярные выражения.info / named.html , ссылка на которую содержится в ответе.
Простой пример:
Для соответствия 1a1
в .NET вы можете использовать
(?<named>(\d)a)\1
Для сопоставления аналогичным образом в PHP вы должны использовать \ 2 вместо
(?<named>(\d)a)\2
Мораль:
Смешивать именованные и пронумерованные группы захвата не рекомендуется, потому что
вкусы несовместимы в том, как нумеруются группы.
Кстати:
Я подготовил этот паттерн \b(?<pool>([A-Z])\1{0,2})(?<number>(\d{1,2}(?!\d)|100))\b
, но затем переключил внимание на разницу, изложенную выше. Вы также можете играть с \1
против \2
в связанной демонстрационной версии.