PHP регулярное выражение без захвата несоответствие группы - PullRequest
15 голосов
/ 10 мая 2011

Я делаю регулярное выражение для даты, и все идет довольно хорошо, я до сих пор понял:

"/(?:[0-3])?[0-9]-(?:[0-1])?[0-9]-(?:20)[0-1][0-9]/"

Он (будем надеяться) будет соответствовать дням и месяцам с одной или двумя цифрами, а также годам с двумя или четырьмя цифрами в 21-м веке. Несколько проб и ошибок позволили мне зайти так далеко.

Но у меня есть два простых вопроса относительно этих результатов:

  1. (?: ) Какое простое объяснение этому? Видимо, это несоответствующая группа. Но тогда ...

  2. Для чего нужен трейлинг ?? например (? )?

Ответы [ 3 ]

30 голосов
/ 10 мая 2011

[Отредактировано (снова) для улучшения форматирования и исправления вступления.]

Это комментарий и ответ.

Часть ответа ... Я согласен с более ранним ответом alex.

  1. (?: ), в отличие от ( ), используется, чтобы избежать захвата текста, как правило, для того, чтобы меньшее количество обратных ссылок добавлялось к тем, которые вы хотите, или для повышения быстродействия.

  2. ? после (?: ) - или после чего-либо, кроме * + ? или {} - означает, что предыдущий элемент может или не может быть найден в рамках законного соответствия. Например, /z34?/ будет соответствовать z3, а также z34, но не будет соответствовать z35 или z и т. Д.

Часть комментариев ... Я сделал то, что могло бы быть улучшением для регулярного выражения, над которым вы работали:

(?:^|\s)(0?[1-9]|[1-2][0-9]|30|31)-(0?[1-9]|10|11|12)-((?:20)?[0-9][0-9])(?:\s|$)

- Во-первых, он избегает таких вещей, как 0-0-2011

- Во-вторых, он избегает таких вещей, как 233443-4-201154564

- В-третьих, оно включает в себя такие вещи, как 1-1-2022

- Далее, это включает в себя такие вещи, как 1-1-11

- В-пятых, он избегает таких вещей, как 34-4-11

- В-шестых, он позволяет вам фиксировать день, месяц и год, чтобы вам было легче ссылаться на них в коде ... коде, который, например, будет выполнять дополнительную проверку (это вторая захваченная группа 2 и является либо первой захваченной группой 29, и это високосный год, либо первая захваченная группа <29), чтобы узнать, подходит ли дата 29 февраля или нет. </p>

Наконец, обратите внимание, что вы все равно получите даты, которых не существует, например, 31-6-11. Если вы хотите избежать этого, попробуйте:

(?:^|\s)(?:(?:(0?[1-9]|[1-2][0-9]|30|31)-(0?[13578]|10|12))|(?:(0?[1-9]|[1-2][0-9]|30)-(0?[469]|11))|(?:(0?[1-9]|[1-2][0-9])-(0?2)))-((?:20)?[0-9][0-9])(?:\s|$)

Кроме того, я предполагал, что перед датами будет стоять пробел (или начало / конец строки), но вы можете отрегулировать его (например, для пунктуации).

Комментатор в другом месте ссылался на этот ресурс, который может оказаться полезным: http://rubular.com/

6 голосов
/ 10 мая 2011
  1. Это группа без захвата.Вы не можете обратно ссылаться на него.Обычно используется для удаления обратных ссылок и / или увеличения производительности.
  2. Это означает, что предыдущая группа захвата является необязательной.
3 голосов
/ 31 августа 2016

Подшаблоны

Подшаблоны ограничиваются круглыми скобками, которые могут быть вложенными.Пометка части шаблона в качестве подшаблона делает две вещи:

  1. . Локализует набор альтернатив.Например, шаблон cat (aract | erpillar |) соответствует одному из слов «кошка», «катаракта» или «гусеница».Без скобок он будет соответствовать «катаракте», «erpillar» или пустой строке.
  2. Он устанавливает подшаблон как захватывающий подшаблон (как определено выше).Когда весь шаблон совпадает, та часть строки субъекта, которая соответствует подшаблону, передается вызывающей стороне через аргумент ovector в pcre_exec ().Открывающие скобки отсчитываются слева направо (начиная с 1), чтобы получить номера захватывающих подшаблонов.

Например, если строка «красный король» сопоставляется с шаблоном ((red | white) (king | queen)) захваченные подстроки - это «red king», «red» и «king» и имеют номера 1, 2 и 3.

Тот факт, что простые скобки соответствуютдве функции не всегда полезны.Часто бывают случаи, когда требуется подгруппа группировки без требования захвата.Если после открывающей скобки следует «?:», Подшаблон не выполняет захват и не учитывается при вычислении количества любых последующих поднаборов.Например, если строка «белая королева» сопоставляется с шаблоном ((?: Red | white) (king | queen)), захваченные подстроки - это «белая королева» и «королева» и имеют номера 1 и 2Максимальное количество захваченных подстрок составляет 65535. Однако, возможно, не удастся скомпилировать такие большие шаблоны в зависимости от параметров конфигурации libpcre.

В качестве удобного сокращения, если какие-либо настройки параметров требуются наначало нефиксирующего подшаблона, буквы опции могут появляться между "?"и ":".Таким образом, два шаблона

(?i:saturday|sunday)
(?:(?i)saturday|sunday)

совпадают в точности с одним и тем же набором строк.Поскольку альтернативные ветви пробуются слева направо, и параметры не сбрасываются до тех пор, пока не будет достигнут конец подшаблона, настройка параметра в одной ветви влияет на последующие ветви, поэтому приведенные выше шаблоны соответствуют «Воскресению», а также «Субботе».

Можно назвать подшаблон с помощью синтаксиса (? Ppattern).Этот подшаблон затем будет проиндексирован в массиве совпадений по его обычной числовой позиции, а также по имени.В PHP 5.2.2 введены два альтернативных синтаксиса (? Pattern) и (? 'Name'pattern).

Иногда необходимо иметь несколько совпадающих, но чередующихся подгрупп в регулярном выражении.Обычно каждому из них присваивается собственный номер обратной ссылки, даже если только один из них когда-либо будет совпадать.Чтобы преодолеть это, синтаксис (? | Позволяет иметь повторяющиеся числа. Рассмотрим следующее регулярное выражение, сопоставленное со строкой Sunday:

(?:(Sat)ur|(Sun))day

Здесь Sun хранится в обратной ссылке 2, а обратная ссылка 1 пуста.в обратной ссылке 1, в то время как обратная ссылка 2. не существует. Изменение шаблона для использования (? | устраняет эту проблему:

(?|(Sat)ur|(Sun))day

При использовании этого шаблона и Sun, и Sat будут сохраняться в обратной ссылке 1.

Ссылка: http://php.net/manual/en/regexp.reference.subpatterns.php

...