Групповая группа non-capture нерегламента PHP regex

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

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

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

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

  • (?: ) что это простое объяснение? По-видимому, это несогласованная группа. Но тогда...

  • Что такое trailing ? for? например (? )?

Ответ 1

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

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

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

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

  • после (?: ) - или при выполнении чего-либо, кроме * + ? или {} - означает, что предыдущий элемент может быть найден или не найден в законном совпадении. Например, /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

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

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

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

Наконец, обратите внимание, что вы все равно получите даты, которые не будут существовать, например, 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|$)

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

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

Ответ 2

  • Это не захватывающая группа. Вы не можете вернуться к нему. Обычно используется для обратных ссылок declutter и/или повышения производительности.
  • Это означает, что предыдущая группа захвата является необязательной.

Ответ 3

Подмаски

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

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

Например, если строка "красный король" сопоставляется с шаблоном ((красный | белый) (царь | королева)), то захваченные подстроки являются "красным королем", "красным" и "королем", и пронумерованы 1, 2 и 3.

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

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

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

соответствует точно такой же набор строк. Поскольку альтернативные ветки проверяются слева направо, а параметры не reset до тех пор, пока не будет достигнут конец подшаблона, параметр в одной ветки влияет на последующие ветки, поэтому вышеуказанные шаблоны соответствуют "ВОСКРЕСЕНЬЕ", а также "Суббота" ".

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

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

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

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

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

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

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