От http://php.net/manual/en/function.preg-quote.php:
preg_quote () принимает ул и ставит обратную косую черту перед каждым символом, который является частью синтаксиса регулярного выражения. Это полезно, если у вас есть строка времени выполнения, которую нужно сопоставить в некотором тексте, и строка может содержать специальные символы регулярного выражения.
Специальные символы регулярного выражения:
. \ + * ? [ ^ ] $ ( ) { } = ! < > | : -
Обратите внимание, что
/
не является специальным символом регулярного выражения.
}
не нужно, но я могу понять, почему они включили его для симметрии. Например. работает следующий код:
$re = '/}{This is fine}{/';
preg_match($re, $re, $match);
var_dump($match);
Выход:
array(1) {
[0] =>
string(16) "}{This is fine}{"}
Почему они включают = ! < > :
? Насколько я могу судить, они только особенные, когда их вводит другой неэкранированный метасимвол, например незамедлительно после (?
, оба из которых символы также экранированы. :
также может быть особенным внутри классов символов, например: [[:alpha:]]
, но все четыре скобки сбежали.
Я думаю, что идея заключается в том, чтобы иметь последовательное поведение.
Цель preg_quote
заключается в создании литеральной строки для шаблона регулярного выражения. Это означает, что ни один символ в возвращаемой строке не может быть интерпретирован как что-то другое, чем он сам, независимо от контекста, и контекст может быть конкатенацией с другой частью шаблона.
Если я напишу '/(?' . preg_quote('>') . 'abc)/'
Я ожидаю, что >
не будет интерпретироваться как >
атомной группы, и что шаблон возвращает ошибку.
Если я напишу '/.{3' . preg_quote('}') . '/'
Я ожидаю, что }
не будет интерпретироваться как закрывающая фигурная скобка квантификатора и что шаблон соответствует строке типа 'a{3}'
, но нет 'abc'
,
Вы можете легко построить такие же примеры для = ! < > :
использование проверочных утверждений, именованных групп, групп без захвата или атомарных групп.
Важно то, что ожидаемое поведение всегда одинаково независимо от способа и контекста, в котором используется функция.
Хорошо, что произойдет, если вы попытаетесь написать какой-то код, подобный этому:
$lookahead = getUserInput(); // Not escaped
$results = preg_match('/abc(?' . $lookahead . ')/', $subject);
и пользователь дает вход !def
? Ответ в том, что вы получаете отрицательный взгляд вместо обычного. Если вы не хотите допускать негативных предупреждений, вам нужно убедиться, что восклицательный знак экранирован.