Документация для?: в регулярных выражениях?

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

пример

$str = 'big blue ball';
$regex = '/b(ig|all)/';
preg_match_all($regex, $str, $matches);
var_dump($matches);

Выходы...

array(2) {
  [0]=>
  array(2) {
    [0]=>
    string(3) "big"
    [1]=>
    string(4) "ball"
  }
  [1]=>
  array(2) {
    [0]=>
    string(2) "ig"
    [1]=>
    string(3) "all"
  }
}

В этом примере меня не волнует, что было найдено в скобках, поэтому я добавил ?: ('/b(?:ig|all)/') и получил вывод

array(1) {
  [0]=>
  array(2) {
    [0]=>
    string(3) "big"
    [1]=>
    string(4) "ball"
  }
}

Это очень полезно - по крайней мере, я так думаю. Иногда вы просто не хотите загромождать совпадения ненужными значениями.

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

Будучи символами, это казалось трудным для Google.

Я также посмотрел на несколько справочников по регулярным выражениям, без упоминания.

Быть с префиксом ?и появление в первых скобках внутри круглых скобок заставило бы меня поверить, что это как-то связано с предвкушением или взглядами назад.

Итак, как правильно их называть, и где я могу узнать больше?

6 ответов

Решение

Это доступно на странице Subpatterns официальной документации.

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

Также хорошо отметить, что вы можете установить опции для подшаблона с ним. Например, если вы хотите, чтобы только подэлемент не учитывал регистр, вы можете сделать:

(?i:foo)bar

Будет соответствовать:

  • Foobar
  • Foobar
  • Foobar
  • ...так далее

Но нет

  • Foobar
  • Foobar
  • ...так далее

Да, и хотя официальная документация на самом деле явно не называет синтаксис, она упоминает его позже как "не захватывающий подшаблон" (что имеет полный смысл, и это то, что я бы назвал в любом случае, поскольку это не совсем так). "группа", но подшаблон)...

(?:) в целом представляет собой группу без захвата.

http://www.regular-expressions.info/brackets.html упоминает этот синтаксис:

Знак вопроса и двоеточие после открывающей круглой скобки - это особый синтаксис, который можно использовать, чтобы указать механизму регулярных выражений, что эта пара скобок не должна создавать обратную ссылку. Обратите внимание, что вопросительный знак [...] является оператором регулярных выражений, который делает предыдущий токен необязательным. Этот оператор не может появляться после открывающей круглой скобки, поскольку сама по себе открывающая скобка не является допустимым токеном регулярного выражения. Следовательно, не существует путаницы между знаком вопроса как оператором, делающим токен необязательным, и знаком вопроса как символом, который изменяет свойства пары круглых скобок. Двоеточие указывает, что изменение, которое мы хотим сделать, это отключить захват обратной ссылки.

Вот что я нашел:

Если вы не используете обратную ссылку, вы можете оптимизировать это регулярное выражение в Set(?:Value)?. Знак вопроса и двоеточие после открывающей круглой скобки - это особый синтаксис, который можно использовать, чтобы указать механизму регулярных выражений, что эта пара скобок не должна создавать обратную ссылку. Обратите внимание, что вопросительный знак после открывающей скобки не связан с вопросительным знаком в конце регулярного выражения. Этот знак вопроса является оператором регулярных выражений, что делает предыдущий токен необязательным. Этот оператор не может появляться после открывающей круглой скобки, поскольку сама по себе открывающая скобка не является допустимым токеном регулярного выражения. Следовательно, не существует путаницы между знаком вопроса как оператором, делающим токен необязательным, и знаком вопроса как символом, который изменяет свойства пары круглых скобок. Двоеточие указывает, что изменение, которое мы хотим сделать, это отключить захват обратной ссылки.

http://www.regular-expressions.info/brackets.html

Это в руководстве по php, и я считаю, что любой другой почти полный раздел регулярных выражений для любого языка...

Тот факт, что простые скобки выполняют две функции, не всегда полезен. Часто бывают случаи, когда требуется подгруппа группировки без требования захвата. Если за открывающей скобкой следует "?:", Подшаблон не выполняет захват и не учитывается при подсчете количества любых последующих поднаборов.

Источник

РНР preg_match_all использует синтаксис PCRE (Perl-Compatible Regular Expression), который описан здесь. Неполные субпаттерны описаны в главе "Подшаблоны".

оставил бы меня верить, что это как-то связано с предвкушением или взглядом назад.

Нет, есть много различных функций, которые запускаются с помощью знака-скобки. Lookahead/lookbehind - это только первая встреча с вами.

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

Я не знаю, как это сделать с?:, Но это легко с простым циклом:

$regex = '/b(ig|all)/';
$array = array(
    0 => array(0 => 'big', 1 => 'ball'),
    1 => array(0 => 'ig', 1 => 'all')
);
foreach ($array as $key => $row) {
    foreach ($row as $val) {
        if (!preg_match($regex, $val)) {
            unset($array[$key]);
        }
    }
}
print_r($array);
Другие вопросы по тегам