2011-06-07 11 views
109

Dado que POSIX regular expressions (ereg) están en desuso desde PHP 5.3.0, me gustaría saber una manera fácil de convertir las expresiones antiguas a PCRE (Perl Compatible Regular Expressions) (preg).¿Cómo puedo convertir expresiones ereg a preg en PHP?

Por ejemplo, tengo esta expresión regular:

eregi('^hello world'); 

¿Cómo puedo traducir expresiones en preg_match expresiones compatibles?

Nota: Este mensaje sirve como un marcador de posición para todos los mensajes relacionados con la conversión de ereg a preg, y como opciones duplicadas para preguntas relacionadas. Por favor, no cierre esta pregunta.

relacionadas:

+2

DE NUEVO? Oh mi Dios la misma pregunta en los últimos diez minutos – dynamic

+2

@ yes123: Sí, ese es el punto, estoy cansado de eso también. Quiero una publicación wiki que realmente explique algo para que podamos cerrar todas estas preguntas individuales. – netcoder

+0

Creo que no es necesario para esto porque solo necesita envolver el anterior con un delimitador. También creo que podrías haber usado una pregunta respondida anterior para esto. – dynamic

Respuesta

106

El mayor cambio en la sintaxis es la adición de delimiters.

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

delimitadores pueden ser casi cualquier cosa que no es alfanumérico, una barra invertida o un carácter de espacio en blanco. Los más utilizados son generalmente ~, / y #.

También puede utilizar los soportes que emparejan:

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

Si se determina que su delimitador en la expresión regular, usted tiene que escapar de ella:

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

Puede escapar fácilmente a todos los delimitadores y caracteres reservados en una cadena usando preg_quote:

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

Además, PCRE admite modifiers para varias cosas. Uno de los más utilizados es el modificador entre mayúsculas y minúsculas i, la alternativa a eregi:

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

Puede encontrar la referencia completa a PCRE syntax in PHP in the manual, así como un list of differences entre POSIX expresiones regulares y PCRE para ayudar a convertir la expresión.

Sin embargo, en el ejemplo sencillo que no se usará una expresión regular:

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

Una respuesta agradable, y probablemente una de las mejores que he visto sobre este tema, ¿por qué hacerlo CW? – Kev

+1

¡Maravillosa explicación! Me gustaría simplemente agregar un caso especial en el que estás convirtiendo de __ereg__ a __preg_match__ y necesitas escapar solo de los delimitadores y no de los caracteres reservados (porque ya estaban trabajando como caracteres especiales, no queremos escapar de ellos) : ** preg_match ('/'. str_replace ('/', '\ /', $ expr). '/', $ str); ** – Lolito

+0

Vale la pena destacar que si usa corchetes iguales, entonces * don 't * necesita escapar de cualquier carácter "solo porque es lo mismo que el delimitador" como lo hace con otros símbolos como el ejemplo '/^\/hello /'. '(a (b) c)' es una PCRE delimitada perfectamente válida. Personalmente, me gusta usar paréntesis '()' para recordarme a mí mismo que el primer partido capturado es todo. –

23

reemplazo Ereg con preg (a partir de PHP 5.3.0) fue movida correcta a nuestro favor.

preg_match, que utiliza una sintaxis de expresiones regulares compatible con Perl, es a menudo una alternativa más rápida a ereg.

Debe saber 4 cosas principales a los patrones Ereg puerto a preg:

  1. Añadir delimitadores (/): 'pattern' => '/pattern/'

  2. Escapar delimitador si se trata de una parte del patrón: 'patt/ern' => '/patt\/ern/'
    Lograrlo programáticamente de la siguiente manera:
    $old_pattern = '<div>.+</div>';
    $new_pattern = '/' . addcslashes($old_pattern, '/') . '/';

  3. eregi (entre mayúsculas y minúsculas juego): 'pattern' => '/pattern/i' Por lo tanto, si usted está utilizando la función eregi para el caso de coincidencia de insenstive, sólo tiene que añadir 'i' en el final del nuevo patrón ('/ patrón/').

  4. Valores ASCII: en ereg, si usa un número en el patrón, se supone que se está refiriendo al ASCII de un carácter. Pero en preg, el número no se trata como valor ASCII. Por lo tanto, si su patrón contiene valor ASCII en la expresión ereg (por ejemplo: nueva línea, pestañas, etc.), conviértalo a hexadecimal y póngalo como prefijo \ x.
    Example: 9(tab) becomes \x9 or alternatively use \t.

2

partir de la versión 5.3 de PHP ereg obsoleta.

Para mover a ereg a preg_match solo pequeño cambio en nuestro patrón

Primero hay que añadir delimitador a su código

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

a

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

Para eregi - caso en sensible a juego puse 'i' después de la última delimitador

por ejemplo

eregi('pattern','string');

a

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

2

Hay más diferencias entre ereg() y preg_replace() que sólo la sintaxis:

  • Valor de retorno:

    • En caso de error: ambos devuelven FALSE
    • En ningún fósforo: ereg() vuelve FALSE, preg_match() devuelve 0
    • Sobre el partido: ereg() devuelve longitud de la cadena o 1, preg_match() vuelve siempre 1
  • Resultado g matriz de subcadenas coincidentes: si no se encuentra alguna subcadena ((b) en ...a(b)?), el resultado correspondiente al ereg() será FALSE, mientras que en preg_match() no se establecerá en absoluto.

Si uno no es lo suficientemente valiente como para convertir su ereg() a preg_match(), él o ella puede utilizar mb_ereg(), que todavía está disponible en PHP 7.