regex — Почему PHP preg_quote экранирует ненужные символы?

От 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:]], но все четыре скобки сбежали.

2

Решение

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

Цель preg_quote заключается в создании литеральной строки для шаблона регулярного выражения. Это означает, что ни один символ в возвращаемой строке не может быть интерпретирован как что-то другое, чем он сам, независимо от контекста, и контекст может быть конкатенацией с другой частью шаблона.

Если я напишу '/(?' . preg_quote('>') . 'abc)/'Я ожидаю, что > не будет интерпретироваться как > атомной группы, и что шаблон возвращает ошибку.

Если я напишу '/.{3' . preg_quote('}') . '/'Я ожидаю, что } не будет интерпретироваться как закрывающая фигурная скобка квантификатора и что шаблон соответствует строке типа 'a{3}', но нет 'abc',

Вы можете легко построить такие же примеры для = ! < > : использование проверочных утверждений, именованных групп, групп без захвата или атомарных групп.

Важно то, что ожидаемое поведение всегда одинаково независимо от способа и контекста, в котором используется функция.

2

Другие решения

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

$lookahead = getUserInput();  // Not escaped
$results = preg_match('/abc(?' . $lookahead . ')/', $subject);

и пользователь дает вход !def? Ответ в том, что вы получаете отрицательный взгляд вместо обычного. Если вы не хотите допускать негативных предупреждений, вам нужно убедиться, что восклицательный знак экранирован.

0

По вопросам рекламы [email protected]