Existe uma função PHP que pode escapar dos padrões de regex antes de serem aplicados?

161

Existe uma função PHP que pode escapar dos padrões de regex antes de serem aplicados?

Eu estou procurando algo ao longo das linhas da Regex.Escape()função c # .

vfclists
fonte

Respostas:

254

preg_quote() é o que você está procurando:

Descrição

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

preg_quote () pega str e coloca uma barra invertida na frente de cada caractere que faz parte da sintaxe da expressão regular. Isso é útil se você tiver uma sequência de tempo de execução que precisa corresponder em algum texto e a sequência pode conter caracteres especiais de expressão regular.

Os caracteres especiais de expressão regular são: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -

Parâmetros

str

A sequência de entrada.

delimitador

Se o delimitador opcional for especificado, ele também será escapado. Isso é útil para escapar do delimitador exigido pelas funções do PCRE. O / é o delimitador mais usado.

Importante, observe que, se o $delimiterargumento não for especificado, o delimitador - o caractere usado para incluir seu regex, geralmente uma barra ( /) - não será escapado. Você geralmente desejará passar o delimitador que estiver usando com o seu regex como $delimiterargumento.

Exemplo - usando preg_matchpara encontrar ocorrências de um determinado URL cercado por espaços em branco:

$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
fonte
11
Uma observação adicional à resposta do @TomHaigh , se você não especificar o segundo $delimiterargumento para preg_quote() ele, não escapará a nenhum delimitador , nem mesmo o "padrão" (ou o mais comum) /.
Alix Axel
Adicionei um monte de coisas a essa resposta - a nota levantada por @AlixAxel sobre a importância do $delimiterargumento, a descrição desse argumento nos documentos, um esclarecimento para os confusos sobre exatamente o que isso significa e uma grande exemplo comentado mostrando preg_quoteser usado no caso mais simples, eu poderia sugerir onde ele realmente está sendo usado para formar programaticamente um regex e colocá-lo em outra preg_*função (porque, caso contrário, qual é o objetivo?). Sinta-se à vontade para reverter se você não gostar da alteração.
Mark Amery
1

Seria muito mais seguro usar Padrões preparados da biblioteca T-Regx :

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

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

então execute a correspondência t-regx normal :

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

$matches = $pattern->match($haystack)->all();
Danon
fonte