Como posso converter expressões ereg para preg em PHP?


140

Como as expressões regulares POSIX (ereg) estão obsoletas desde o PHP 5.3.0, eu gostaria de saber uma maneira fácil de converter as expressões antigas em PCRE (Expressões regulares compatíveis com Perl) (preg) .

Por exemplo, eu tenho essa expressão regular:

eregi('^hello world');

Como posso traduzir expressões em preg_matchexpressões compatíveis?

Nota: esta postagem serve como um espaço reservado para todas as postagens relacionadas à conversão de ereg para preg e como opções duplicadas para perguntas relacionadas. Por favor, não feche esta pergunta.

Palavras-chave:


2
@ yes123: Sim, esse é o ponto, também estou cansado disso. Quero um post na wiki que realmente explique algo para que possamos fechar todas essas perguntas individuais.
— Netcoder

Eu acho que não há necessidade disso, porque você só precisa envolver o antigo com um delimitador. Também acho que você poderia ter usado uma pergunta respondida anterior para isso.
— dinâmica

Ah, votei no fim antes de ler os comentários. Como espaço reservado, isso pode servir a um propósito, mas não há outra pergunta antiga que poderia ter servido como tal?
— Wrikken

Hmm, de fato. ereg [php]não produz resultados muito úteis. OK, posso dar meu apoio a este.
— Wrikken

8
Pessoal, parece que quase criamos um círculo de perguntas fechadas sobre esse tópico, todas apontando uma para a outra. A este ritmo que vai tudo ser fechado :)
— Kev

Respostas:


142

A maior mudança na sintaxe é a adição de delimitadores .

ereg('^hello', $str);
preg_match('/^hello/', $str);

Os delimitadores podem ser praticamente qualquer coisa que não seja alfanumérica, uma barra invertida ou um caractere de espaço em branco. Os mais utilizados são geralmente ~,/ e #.

Você também pode usar colchetes correspondentes:

preg_match('[^hello]', $str);
preg_match('(^hello)', $str);
preg_match('{^hello}', $str);
// etc

Se o seu delimitador for encontrado na expressão regular, você deverá escapar dele:

ereg('^/hello', $str);
preg_match('/^\/hello/', $str);

Você pode escapar facilmente de todos os delimitadores e caracteres reservados em uma string usando preg_quote :

$expr = preg_quote('/hello', '/');
preg_match('/^'.$expr.'/', $str);

Além disso, o PCRE suporta modificadores para várias coisas. Um dos mais utilizados é o modificador ique não diferencia maiúsculas de minúsculas , a alternativa ao eregi. :

eregi('^hello', 'HELLO');
preg_match('/^hello/i', 'HELLO');

Você pode encontrar a referência completa à sintaxe PCRE no PHP no manual , bem como uma lista de diferenças entre o POSIX regex e o PCRE para ajudar a converter a expressão.

No entanto, no seu exemplo simples, você não usaria uma expressão regular:

stripos($str, 'hello world') === 0

2
Explicação maravilhosa! Gostaria apenas de adicionar um caso especial no qual você está convertendo de ereg para preg_match e precisa escapar apenas dos delimitadores e dos caracteres não reservados (porque eles já estavam trabalhando como caracteres especiais, não queremos que eles escapem) : preg_match ('/'. str_replace ('/', '\ /', $ expr). '/', $ str);
— Lolito

É particularmente importante notar que, se você usar colchetes correspondentes, não precisará escapar de nenhum caractere "apenas porque é o mesmo que o delimitador", como acontece com outros símbolos como o /^\/hello/exemplo. (a(b)c)é um PCRE delimitado, perfeitamente válido. Pessoalmente, gosto de usar parênteses ()para me lembrar que a primeira partida capturada é a coisa toda.
— Niet the Dark Absol

Posso dizer, eu odeio PHP! (.. Só que nada mais) eu tenho que procurar essas respostas fora quando o meu servidor de hospedagem compartilhada da Web é atualizado para uma nova versão e os error_logs se completa com estas advertências: PHP Deprecated: Function ereg() is deprecated in.... Argh!
— C00000fd

como converter isso? $ regex = $ e. '((\. [^ \.'. $ e. '] [^'. $ e. '] *) | (\. \. [^'. $ e. '] +) | ([^ \. ] [^ '. $ e.'] *)) '. $ e. '\. \.' . $ e; para preg_math-lo trabalho fizerem apenas adicionando / modificador /
— bdalina

32

A substituição de Ereg por preg (a partir do PHP 5.3.0) foi a jogada certa a nosso favor.

preg_match, que usa uma sintaxe de expressão regular compatível com Perl, geralmente é uma alternativa mais rápida ao ereg.

Você deve conhecer quatro coisas principais para portar padrões ereg para preg:

  1. Adicione delimitadores (/):'pattern' => '/pattern/'

  2. Delimitador de escape se fizer parte do padrão: 'patt/ern' => '/patt\/ern/'
    obtenha-o programaticamente da seguinte maneira:
    $old_pattern = '<div>.+</div>';
    $new_pattern = '/' . addcslashes($old_pattern, '/') . '/';

  3. eregi (correspondência sem distinção entre maiúsculas e minúsculas): 'pattern' => '/pattern/i' Portanto, se você estiver usando a função eregi para correspondência sem distinção entre maiúsculas e minúsculas, basta adicionar 'i' no final do novo padrão ('/ pattern /').

  4. Valores ASCII : Em geral, se você usar número no padrão, presume-se que você esteja se referindo ao ASCII de um caractere. Mas em preg, o número não é tratado como valor ASCII. Portanto, se seu padrão contiver valor ASCII na expressão ereg (por exemplo: nova linha, tabulações etc.), converta-o em hexadecimal e prefixe-o com \ x.
    Example: 9(tab) becomes \x9 or alternatively use \t.


8

Do PHP versão 5.3, eregestá obsoleto.

Passar de eregpara preg_matché apenas uma pequena mudança em nosso padrão.

Primeiro, você precisa adicionar delimitadores ao seu código, por exemplo:

ereg('A-Z0-9a-z', 'string');

para

preg_match('/A-Z0-9a-z/', 'string');

Para eregicorrespondência sem distinção entre maiúsculas e minúsculas, coloque iapós o último delimitador, por exemplo:

eregi('pattern', 'string');

para

preg_match ('/pattern/i', 'string');

7

Existem mais diferenças entre ereg()e preg_replace()além da sintaxe:

  • Valor de retorno:

    • Em erro : ambos retornamFALSE
    • Em partida : ereg()retornos FALSE, preg_match()retornos0
    • Na partida : ereg()retorna o comprimento da string ou 1, preg_match()sempre retorna1
  • Matriz resultante de substrings correspondentes: Se alguma substring não for encontrada ( (b)in ...a(b)?), o item correspondente no ereg()resultado será FALSE, enquanto o item preg_match()não será definido.

Se um não é corajoso o suficiente para converter o seu ereg()para preg_match(), ele ou ela pode usar mb_ereg () , que ainda está disponível no PHP 7.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.