Czy istnieje funkcja PHP, która może unikać wzorców regex przed ich zastosowaniem?

161

Czy istnieje funkcja PHP, która może unikać wzorców regex przed ich zastosowaniem?

Szukam czegoś na wzór funkcji C # Regex.Escape().

vfclists
źródło

Odpowiedzi:

254

preg_quote() to czego szukasz:

Opis

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

preg_quote () pobiera str i umieszcza ukośnik odwrotny przed każdym znakiem, który jest częścią składni wyrażenia regularnego. Jest to przydatne, jeśli masz ciąg czasu wykonywania, który musisz dopasować w jakimś tekście, a ciąg może zawierać specjalne znaki wyrażenia regularnego.

Specjalne znaki wyrażenia regularnego to: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -

Parametry

str

Ciąg wejściowy.

ogranicznik

Jeśli określono opcjonalny separator, również zostanie on zmieniony. Jest to przydatne przy unikaniu ogranicznika wymaganego przez funkcje PCRE. / Jest najczęściej używanym separatorem.

Co ważne, zauważ, że jeśli $delimiterargument nie zostanie określony, separator - znak używany do ujęcia wyrażenia regularnego, zwykle ukośnik ( /) - nie zostanie zmieniony. Zwykle będziesz chciał przekazać dowolny separator, którego używasz, ze swoim wyrażeniem regularnym jako $delimiterargumentem.

Przykład - użycie preg_matchdo znalezienia wystąpień podanego adresu URL otoczonych białymi znakami:

$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 "
// }
Tom Haigh
źródło
11
Jedna dodatkowa uwaga do odpowiedzi @TomHaigh , jeśli nie podasz do niej drugiego $delimiterargumentu, preg_quote() nie będzie żadnego ogranicznika , nawet „domyślnego” (lub najczęściej używanego) /.
Alix Axel
Do tej odpowiedzi dodałem całą masę rzeczy - notatka wywołana przez @AlixAxel na temat wagi $delimiterargumentu, opis tego argumentu z dokumentacji, wyjaśnienie dla zdezorientowanych, co dokładnie oznacza, i mocno skomentował przykład pokazujący, preg_quoteże jest używany w najprostszym przypadku, jaki mogłem wymyślić, gdzie faktycznie jest używany do programowego tworzenia wyrażenia regularnego i umieszczania go w innej preg_*funkcji (bo w przeciwnym razie o co chodzi?). Jeśli nie podoba Ci się ta zmiana, możesz ją wycofać.
Mark Amery,
1

Znacznie bezpieczniej byłoby użyć gotowych wzorów z biblioteki T-Regx :

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

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

następnie przeprowadź normalne dopasowanie t-regx :

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

$matches = $pattern->match($haystack)->all();
Danon
źródło