Чи є функція PHP, яка може уникнути шаблонів регулярних виразів перед їх застосуванням?


161

Чи є функція PHP, яка може уникнути шаблонів регулярних виразів перед їх застосуванням?

Я шукаю щось за принципом функції C # Regex.Escape().

Відповіді:


254

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();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.