Foros del Web » Programando para Internet » PHP »

Duda con expresiones regulares

Estas en el tema de Duda con expresiones regulares en el foro de PHP en Foros del Web. Hola a tod@s. Tengo un problema aparentemente muy simple pero al que no le he logrado dar solución. Quiero hacer algo parecido a un parser ...
  #1 (permalink)  
Antiguo 06/12/2007, 13:56
Avatar de qwerty_wq  
Fecha de Ingreso: enero-2005
Mensajes: 109
Antigüedad: 19 años, 2 meses
Puntos: 1
Duda con expresiones regulares

Hola a tod@s. Tengo un problema aparentemente muy simple pero al que no le he logrado dar solución. Quiero hacer algo parecido a un parser XML, pero sin usar el que trae PHP, empleando expresiones regulares. Así, por ejemplo, si quiero leer el contenido de una etiqueta:

<etiqueta>Contenido de la eqtiqueta</etiqueta>

Podría usar una sentencia similar a:

Código:
preg_match('/<etiqueta>([^<]+)<\/etiqueta>/', $fichero_xml, $res);
Ahora bien, ¿qué pasa si el contenido de la etiqueta es éste?:

<etiqueta>En este Universo 7 < 8 se cumple siempre</etiqueta>

Obviamente no me leerá el contenido correctamente, ya que encontrará un caracter '<' que limitará la expresión regular y hará que no se cumpla.

Mi pregunta es, ¿cómo se puede indicar en una expresión regular que NO aparezca una cadena? Es decir, sería algo así como excluir una clase mediante [^<] sólo que en lugar de caracteres excluir palabras o cadenas. Es decir, lo que quiero es leer el contenido de una etiqueta hasta que encuentre el cierre, pero explicitando la etiqueta de cierre en la expresión regular de preg_match.

No sé si me habré explicado

Un saludo y gracias de antemano a las posibles respuestas
  #2 (permalink)  
Antiguo 06/12/2007, 14:47
 
Fecha de Ingreso: noviembre-2007
Mensajes: 157
Antigüedad: 16 años, 5 meses
Puntos: 3
Re: Duda con expresiones regulares

Bueno, es ilegal poner el carácter '<' (hay que escribir &lt;, como en html) en xml, así que yo no me preocuparía.
  #3 (permalink)  
Antiguo 06/12/2007, 15:55
Avatar de qwerty_wq  
Fecha de Ingreso: enero-2005
Mensajes: 109
Antigüedad: 19 años, 2 meses
Puntos: 1
Re: Duda con expresiones regulares

Bueno, en realidad lo del XML era un ejemplo para que se entendiera, en realidad lo que voy a "parsear" es mi propio lenguaje de etiquetas que empleo para almacenar internamente datos estructurados en un campo de MySQL. Las etiquetas tienen este aspecto:

#1#Contenido del campo@1@

Como véis, se trata igualmente de apertura y cierre, y tiene el mismo problema que podría encontrarse en XML con < y >, sólo que no es exactamente igual y en el contenido del campo puede haber cualquier caracter, incluyendo saltos de línea, espacios, tabulaciones, caracteres "extraños" de Unicode...

Pues eso.
  #4 (permalink)  
Antiguo 06/12/2007, 18:34
Avatar de emiliodeg  
Fecha de Ingreso: septiembre-2005
Ubicación: Córdoba
Mensajes: 1.830
Antigüedad: 18 años, 7 meses
Puntos: 55
Re: Duda con expresiones regulares

proba con esta

preg_match('/<etiqueta>([.]+)<\/etiqueta>/', $fichero_xml, $res);

ademas podrias cambiar el + por un * pq puede q venga vacio el contenido
__________________
Degiovanni Emilio
developtus.com
  #5 (permalink)  
Antiguo 08/12/2007, 01:27
 
Fecha de Ingreso: noviembre-2007
Mensajes: 157
Antigüedad: 16 años, 5 meses
Puntos: 3
Re: Duda con expresiones regulares

Prueba escapando los caracteres. Pero sin saber exactamente qué patrones quieres utilizar no consigo sacarlo en claro. En el caso que propones, no es necesario negar el caracter < por ejemplo. ¿Un ejemplo más completo? xD
__________________
Fondos de pantalla de anime

Última edición por Lanselot; 08/12/2007 a las 01:42
  #6 (permalink)  
Antiguo 10/12/2007, 11:54
Avatar de qwerty_wq  
Fecha de Ingreso: enero-2005
Mensajes: 109
Antigüedad: 19 años, 2 meses
Puntos: 1
Re: Duda con expresiones regulares

Bueno, el problema es muy simple (no sé si sencillo). Tengo una etiqueta de apertura y otra de cierre con esta forma:

Código:
#1#Contenido de la etiqueta@1@
Evidentemente, para leer esto sólo haría falta hacer:

Código:
preg_match('/#1#([^@]*)@1@/', $fichero_xml, $resultados);
Obviamente se escaparían los caracteres necesarios, pero ése no es el problema. Supongamos que ahora queremos leer el siguiente contenido:

Código:
#1#Mi email es [email protected]@1@
La expresión regular anterior no vale, porque en el contenido de la matriz se incluye el carácter @ que invalida el patrón. Por lo tanto el problema tiene lugar cuando dentro del contenido hay uno de los caracteres de la etiqueta de cierre. Lo ideal sería que la expresión regular dijera algo como lo que sigue:

Cita:
La cadena #1# seguida de varios caracteres que no formen @1@ hasta que se encuentre @1@
Pues eso es lo que quiero hacer, y que no encuentro el modo de conseguirlo.

Un saludo y muchas gracias a todos los que han contestado

A ver si se os ocurre algo
  #7 (permalink)  
Antiguo 10/12/2007, 20:53
 
Fecha de Ingreso: noviembre-2007
Mensajes: 157
Antigüedad: 16 años, 5 meses
Puntos: 3
Re: Duda con expresiones regulares

es que para lo que propones, basta con usar
Código PHP:
$fichero_xml='La cadena #1# seguida de varios caracteres que no formen @1@ hasta que se encuentre @1@';
preg_match('/#1#.*@1@/'$fichero_xml,$resultados
Con eso, obtendrías "#1# seguida de varios caracteres que no formen @1@ hasta que se encuentre @1@"

Luego, con esto:
Código PHP:
$fichero_xml='La cadena #1# seguida de varios caracteres que no formen @1@ hasta que se encuentre @1@';
preg_match('/#1#.*@1@/U'$fichero_xml,$resultados
obtendrías "#1# seguida de varios caracteres que no formen @1@".

Aunque quizás no quieres ni lo uno ni lo otro, por eso pedía un ejemplo más completo.

Saludos
__________________
Fondos de pantalla de anime
  #8 (permalink)  
Antiguo 11/12/2007, 12:21
Avatar de qwerty_wq  
Fecha de Ingreso: enero-2005
Mensajes: 109
Antigüedad: 19 años, 2 meses
Puntos: 1
Re: Duda con expresiones regulares

Muchísimas gracias, Lanselot, me parece que sin entendernos ambos del todo has logrado darme la pista que resuelve el problema. Dicha pista radica en el modificador U que vuelve a los cuantificadores menos "codiciosos" y tienden a coger el resultado más "pequeño" que cumpla con el patrón:

http://es.php.net/manual/es/referenc....modifiers.php

Y el problema era éste:

Código:
$string = '-----#1#El primer email es [email protected]@1@-----#1#El segundo email es [email protected]@1@-----';
preg_match('/#1#(.*)@1@/', $string, $res);
Si entendemos '-----' por contenido "de relleno" que no es importante, está claro que ahí hay dos etiquetas cuyo contenido quiere leerse. Si ejecutamos el código anterior, $res[1] contendrá lo siguiente:

Cita:
El primer email es [email protected]@1@-----#1#El segundo email es [email protected]
Sin embargo, una solución que podría ser leer el contenido con esta sentencia:

Código:
preg_match('/#1#([^@]*)@1@/', $string, $res);
No sirve para nada, porque hay una arroba dentro del contenido de las dos etiquetas. La clave, por tanto, es hacer a los cuantificadores menos "codiciosos" y que detecten el contenido menos amplio que cumpla con el patrón.

Un saludo y muchísimas gracias por todo

PD: esto del modificador U debería aparecer en la información de preg_match en php.net de forma clara, ya que si queremos hacer un parser XML "casero" (o similar, que es lo que quiero hacer) vamos a necesitarlo de forma irremediable. Además, en muchas aplicaciones nos puede interesar coger el contenido más "pequeño" que cumpla la expresión regular en lugar del más largo. Se me ocurre, por ejemplo, un "traductor" de código phpBB.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 05:36.