W3docs

quotemeta()

Статья о функции PHP quotemeta(), которая экранирует метасимволы в строке для использования в регулярных выражениях.

Функция PHP quotemeta() добавляет обратный слеш перед каждым символом, имеющим специальное значение в регулярном выражении, и возвращает новую «экранированную» строку. Используйте её, когда нужно взять произвольный текст и сопоставить его буквально внутри шаблона, чтобы символы вроде ., * или ( воспринимались как обычный текст, а не операторы регулярных выражений.

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

Синтаксис

quotemeta(string $str): string

Функция принимает один аргумент:

  • $str — входная строка для экранирования.

Она возвращает новую строку с экранированными специальными символами. Исходная строка не изменяется. Если $str — пустая строка, возвращается пустая строка.

Какие символы экранируются

quotemeta() ставит обратный слеш перед каждым из следующих символов:

.  \  +  *  ?  [  ^  ]  $  (  )

Это полный список. Всё, что не входит в этот набор — включая !, ,, =, -, {, } и | — остаётся без изменений. Это частый источник путаницы: quotemeta() не экранирует все «пунктуационные» символы, а только одиннадцать перечисленных выше.

Простой пример

php— editable, runs on the server

Результат:

Hello\^World!

Символ ^ экранируется, поскольку является метасимволом регулярного выражения, тогда как ! остаётся без изменений — он не входит в экранируемый набор.

Более полный пример

Чтобы увидеть полное поведение функции, экранируем строку, содержащую несколько метасимволов:

<?php
$pattern = 'price: $9.99 (per item)*';
echo quotemeta($pattern);
?>

Вывод:

price: \$9\.99 \(per item\)\*

Обратите внимание: пробел, двоеточие и цифры остались без изменений, а $, ., (, ) и * получили обратный слеш.

Зачем это нужно

Смысл экранирования — сопоставлять введённый пользователем текст буквально. Без экранирования поисковый запрос вроде a.b будет соответствовать axb, a-b и любому другому варианту a + символ + b, потому что . в регулярных выражениях означает «любой символ»:

<?php
$term = 'a.b';
$haystack = 'axb';

// Unescaped: '.' acts as a wildcard and matches 'x'
var_dump((bool) preg_match("/$term/", $haystack));

// Escaped: '.' is treated literally, so it does not match
$escaped = quotemeta($term);
var_dump((bool) preg_match("/$escaped/", $haystack));
?>

Вывод:

bool(true)
bool(false)

quotemeta() vs preg_quote()

quotemeta() появилась до того, как в PHP появился движок PCRE, и не экранирует все символы, которые PCRE считает специальными — например, {, }, | и /. Кроме того, она не умеет экранировать разделитель шаблона.

Для PCRE-шаблонов (preg_match(), preg_replace() и подобных) почти всегда предпочтительнее использовать preg_quote(), которая экранирует полный набор метасимволов PCRE и принимает необязательный аргумент-разделитель, чтобы экранировать и его тоже:

<?php
$term = 'a/b';
echo preg_quote($term, '/'); // a\/b
?>

Используйте quotemeta() только для ограниченных случаев в стиле POSIX, для которых она была создана; для всего, что связано с регулярными выражениями в современном PHP, используйте preg_quote().

Связанные функции

  • preg_quote() — экранирование строки для использования в PCRE-шаблоне (рекомендуемый вариант).
  • preg_match() — выполнение сопоставления с регулярным выражением.
  • preg_replace() — поиск и замена с использованием регулярного выражения.
  • addslashes() — экранирование кавычек и обратных слешей для строковых литералов, а не регулярных выражений.

Практика

Практика
Какие из следующих символов экранируются функцией quotemeta() в PHP?
Какие из следующих символов экранируются функцией quotemeta() в PHP?
Was this page helpful?