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


Некоторое время назад я видел в регулярном выражении (по крайней мере, в 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.

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

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

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

 27
Author: alex, 2010-09-28

6 answers

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

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

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

(?i:foo)bar

Будет совпадение:

  • фубар
  • Фубар
  • Фубар
  • ...и т.д.

Но не

  • Фубар
  • Фубар
  • ...и т.д.

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

 29
Author: ircmaxell, 2010-09-28 12:44:28

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

Regular-expressions.info упоминает этот синтаксис:

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

 7
Author: Julien Hoarau, 2010-09-28 12:36:24

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

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

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

 3
Author: Ruel, 2010-09-28 12:37:52

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

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

Источник

 3
Author: poke, 2010-09-28 12:41:15

PHP preg_match_all использует синтаксис PCRE (Регулярное выражение, совместимое с Perl), который задокументирован здесь . Подшаблоны без захвата описаны в главе Подшаблоны.

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

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

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

 2
Author: bobince, 2010-09-28 12:45:50

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

$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);
 0
Author: pltvs, 2010-09-28 12:41:35