Есть ли функция PHP, которая может избежать шаблонов регулярных выражений, прежде чем они будут применены?

162

Есть ли функция PHP, которая может избежать шаблонов регулярных выражений, прежде чем они будут применены?

Я ищу что-то вроде Regex.Escape()функции C # .

vfclists
источник

Ответы:

255

preg_quote() это то, что вы ищете:

Описание

string preg_quote ( string $str [, string $delimiter = NULL ] )

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

Специальные символы регулярного выражения: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -

параметры

ул

Строка ввода.

ограничитель

Если указан дополнительный разделитель, он также будет экранирован. Это полезно для экранирования разделителя, который требуется для функций PCRE. / Является наиболее часто используемым разделителем.

Важно отметить, что если $delimiterаргумент не указан, разделитель - символ, используемый для включения вашего регулярного выражения, обычно косая черта ( /) - не будет экранирован. Вы обычно хотите передать любой разделитель, который вы используете, с вашим регулярным выражением в качестве $delimiterаргумента.

Пример - использование preg_matchдля поиска вхождений данного URL в окружении пробелов:

$url = 'http://stackoverflow.com/questions?sort=newest';

// preg_quote escapes the dot, question mark and equals sign in the URL (by
// default) as well as all the forward slashes (because we pass '/' as the
// $delimiter argument).
$escapedUrl = preg_quote($url, '/');

// We enclose our regex in '/' characters here - the same delimiter we passed
// to preg_quote
$regex = '/\s' . $escapedUrl . '\s/';
// $regex is now:  /\shttp\:\/\/stackoverflow\.com\/questions\?sort\=newest\s/

$haystack = "Bla bla http://stackoverflow.com/questions?sort=newest bla bla";
preg_match($regex, $haystack, $matches);

var_dump($matches);
// array(1) {
//   [0]=>
//   string(48) " http://stackoverflow.com/questions?sort=newest "
// }
Том Хей
источник
11
Еще одно замечание к ответу @TomHaigh , если вы не укажете второй $delimiterаргумент для preg_quote() него, не будет исключен ни один разделитель , даже «по умолчанию» (или самый распространенный) /.
Аликс Аксель
Я добавил к этому ответу целую кучу вещей - заметку, поднятую @AlixAxel о важности $delimiterаргумента, описание этого аргумента из документов, разъяснение для запутанного о том, что именно это означает, и в значительной степени прокомментированный пример, демонстрирующий preg_quoteиспользование в простейшем случае, я мог бы придумать, где он фактически используется для программного формирования регулярного выражения и помещения его в другую preg_*функцию (потому что иначе, какой смысл?). Не стесняйтесь откат, если вам не нравятся изменения.
Марк Эмери
1

Было бы гораздо безопаснее использовать готовые шаблоны из библиотеки T-Regx :

$url = 'http://stackoverflow.com/questions?sort=newest';

$pattern = Pattern::prepare(['\s', [$url], '\s']);
                                // ↑ $url is quoted

затем выполните нормальное совпадение t-regx :

$haystack = "Bla bla http://stackoverflow.com/questions?sort=newest bla bla";

$matches = $pattern->match($haystack)->all();
Danon
источник