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:

codificador de rede
fonte
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
netcoder
fonte
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.

Sumoanand
fonte
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');
Narayan
fonte
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.

Roman Hocke
fonte