Foros del Web » Programando para Internet » PHP »

Encontrar html con expresiones regulares

Estas en el tema de Encontrar html con expresiones regulares en el foro de PHP en Foros del Web. Necesito encontrar todos los links que incluyan <h2> o <h3> dentro. Tengo esto, que funciona casi perfectamente. Digo casi, porque hay tres link sin subtitulos ...
  #1 (permalink)  
Antiguo 07/04/2010, 10:28
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 1 mes
Puntos: 101
Encontrar html con expresiones regulares

Necesito encontrar todos los links que incluyan <h2> o <h3> dentro.

Tengo esto, que funciona casi perfectamente. Digo casi, porque hay tres link sin subtitulos que se filtran:

$patron = '/<a(.*)><h[32]>(.*)<\/h[32]>.*<\/a>/isU';

Lo que esta pasando con ese filtro es que se seleccionan, aunque no siempre, estas estructuras:

Cita:
<a href="http://www.artofillusion.org">www.artofillusion.org</a><br><a href="textures.html"><strong><h2>5.1 Textures</h2></strong></a>
Es decir, la primera etiqueta siente que tiene que encontrar un sibtitulo sí o sí, y se come a la segunda etiqueta (hace lo que marco en rojo).

Esto no debería pasar, porque tengo el modificador /U (de codicia). Sin embargo, sucede con solo 3 o 4 links de los 40 que tengo!. Y no veo por qué.

Me parece que el problema esta en el primer selector:

<a(.*)>

Lo que necesito es negar que dentro de (.*) exista la cadena </a>

Y ya he intentado mil cosas, pero no funcionan: <a([^>]?)>
  #2 (permalink)  
Antiguo 07/04/2010, 10:32
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Encontrar html con expresiones regulares

de hecho, si se puede... solo debes pensar que el punto . es muy permisivo... y en lugar de decir "todo lo que puedas", debes especificar "todo excepto" con lo que se detiene sin necesidad de el modificador U
Cita:
<a[^>]*>
y bueno, estaba bien tu expresión... solo debes reflexionar mas como utilizar los comodines y modificadores... ;)

en tu ejemplo [^>]? se toma solo como un carácter, y eso era lo que te fallaba...
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #3 (permalink)  
Antiguo 07/04/2010, 10:37
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 1 mes
Puntos: 101
Respuesta: Encontrar html con expresiones regulares

Gracias. Pero también probé con eso y no funciona. Probé varias cosas (casi siempre con el cuantificador *).

Desde hace unos días estoy estudiando expresiones regulares. Ya avancé mucho. En parte gracias a ustedes!

Pero con esto, por mas que le de vueltas... no encuentro solución. Mira:
Cita:
$patron = '/<a[^>]*>.*<h[32]>(.*)<\/h[32]>.*<\/a>/is';
Con /U o sin /U no me funciona.

Tampoco:

'/<a[^<]+>.*<h[32]>(.*)<\/h[32]>.*<\/a>/is'

Ni:
'/<a[^>]*>[^(a>)]*<h[32]>.*<\/h[32]>.*<\/a>/isU';

Última edición por mayid; 07/04/2010 a las 11:34
  #4 (permalink)  
Antiguo 07/04/2010, 12:08
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 1 mes
Puntos: 101
Respuesta: Encontrar html con expresiones regulares

Esto es valido?

[^(a>)]*

Necesito agrupar a> y negarlo.
  #5 (permalink)  
Antiguo 07/04/2010, 12:11
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Tokyo - Japan !
Mensajes: 3.867
Antigüedad: 14 años, 6 meses
Puntos: 334
Respuesta: Encontrar html con expresiones regulares

no, no es valido...
y yo e preguntado por todos lados sin respuestas de como negar palabras con regex y nadie sabe x3
__________________
More about me...
~ @rhyudek1
~ Github
  #6 (permalink)  
Antiguo 07/04/2010, 12:17
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 1 mes
Puntos: 101
Respuesta: Encontrar html con expresiones regulares

Que pena. No encuentro más solución a esto mas que negar un grupo de caracteres.

Por otro lado, estoy probando mi expresión en una web, y me dicen esto:
Cita:
Please note that no escaping is applied to supplied regular expressions. You got to escape your regexes properly yourself.
http://www.spaweditor.com/scripts/regex/index.php

Que es lo que tengo que escapar? De que se trata?
  #7 (permalink)  
Antiguo 07/04/2010, 12:25
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Tokyo - Japan !
Mensajes: 3.867
Antigüedad: 14 años, 6 meses
Puntos: 334
Respuesta: Encontrar html con expresiones regulares

usa el programa regexbuddy que me recomendo un usuario del foro
te da la informacion detallada de lo que estas haciendo y otras cosas mas
__________________
More about me...
~ @rhyudek1
~ Github
  #8 (permalink)  
Antiguo 07/04/2010, 12:26
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 1 mes
Puntos: 101
Respuesta: Encontrar html con expresiones regulares

Ok. REspecto a lo que no encontramos... creo que tengo una pista:
http://www.codingforums.com/showthread.php?t=69898

Se trata de "look behind" y "look forward". Con eso se encuentran seguidillas de caracteres. Pero aún no se como negarlos.
  #9 (permalink)  
Antiguo 07/04/2010, 12:47
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 1 mes
Puntos: 101
Respuesta: Encontrar html con expresiones regulares

Resuelto!

Queda así:
$patron = '/<a[^>]*>(.(?!a>))*<h[32]>.*<\/h[32]>.*<\/a>/isU';

La cadena con look ahead:

(.(?!a>))*

Se asegura de que no se cierre la etiqueta <a>

Documentación:
http://www.ibm.com/developerworks/op...os-php-regex2/
http://www.perlmonks.org/?node_id=518444

Gracias!!
  #10 (permalink)  
Antiguo 07/04/2010, 12:50
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Tokyo - Japan !
Mensajes: 3.867
Antigüedad: 14 años, 6 meses
Puntos: 334
Respuesta: Encontrar html con expresiones regulares

y yo que lo estaba haciendo..

bueno este fue el resultado
Código PHP:
Ver original
  1. <?php
  2. $texto = '<a href="http://www.artofillusion.org">www.artofillusion.org</a><br><a href="textures.html"><strong><h2>5.1 Textures</h2></strong></a>';
  3. preg_match('%<a([^>]*)>.*<h([32])>.*</h\2>.*</a>%is', $texto, $matches);
  4. print_r($matches);
  5. ?>


PD: gracias por la info...
apenas recuerde para que lo necesitaba tanto hace un tiempo lo usare :P
__________________
More about me...
~ @rhyudek1
~ Github
  #11 (permalink)  
Antiguo 07/04/2010, 12:56
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 1 mes
Puntos: 101
Respuesta: Encontrar html con expresiones regulares

Bueno, gracias por probar!

Sinceramente, no se por qué para algunos resultados me hacía Greedy y para otros no!

La cosa es que ya está resuelto. Pero igual te comento que esto: .* no resultaba:
Cita:
<a([^>]*)>.*<h([32])>
  #12 (permalink)  
Antiguo 07/04/2010, 13:08
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Tokyo - Japan !
Mensajes: 3.867
Antigüedad: 14 años, 6 meses
Puntos: 334
Respuesta: Encontrar html con expresiones regulares

ajjajaa depende de como hagas la expresion =)
te adjunto la imagen del regexbuddy que afirma que si funciona
prueba de la verdad

__________________
More about me...
~ @rhyudek1
~ Github
  #13 (permalink)  
Antiguo 07/04/2010, 13:12
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 1 mes
Puntos: 101
Respuesta: Encontrar html con expresiones regulares

Buenisimo!

Esto tendrá que ver?

<h([32])>.*</h\2>

Me gusta. Es menos monstruosa que la que me resultó a mi!
  #14 (permalink)  
Antiguo 07/04/2010, 13:28
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Tokyo - Japan !
Mensajes: 3.867
Antigüedad: 14 años, 6 meses
Puntos: 334
Respuesta: Encontrar html con expresiones regulares

no, yo creo mas que nada por que le di mas firmeza a la expresion y elimine el Ungreedy
__________________
More about me...
~ @rhyudek1
~ Github
  #15 (permalink)  
Antiguo 07/04/2010, 14:00
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 1 mes
Puntos: 101
Respuesta: Encontrar html con expresiones regulares

Hay! Pero el ungreedy es tan necesario!

Me encantaría poder mostrarte el codigo que tengo que filtrar. Probe el tuyo y me hace selecciones enormes, casi de paginas enteras, te diría.

Pero no sigamos. Creo el gran decisor puede ser el flag:

Cita:
$patron = '/<a[^>]*>(.(?!a>))*<h[32]>.*<\/h[32]>.*<\/a>/isU'; //|<a.*>.*<h3>(.*)<\/h3>.*<\/a> // [^(<\/a>)]+
//$patron = '/<a name="(.*)">(.*)<\/a>/isU';

preg_match_all($patron, trim($section['sections']), $subtitle, PREG_SET_ORDER);

for($i=0;$i<count($subtitle);$i++){
if (isset($subtitle[$i][0])){
$subtitulos[] = strip_tags(trim($subtitle[$i][0]), "<a>");
}
}
Aun no estoy tan suelto con estas expresiones como para asegurar que algo funcione.
  #16 (permalink)  
Antiguo 07/04/2010, 14:03
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Tokyo - Japan !
Mensajes: 3.867
Antigüedad: 14 años, 6 meses
Puntos: 334
Respuesta: Encontrar html con expresiones regulares

podrias subirlo a un servidor en un txt para revisarlo aca?
no me gusta perder contra las regex
x3
__________________
More about me...
~ @rhyudek1
~ Github
  #17 (permalink)  
Antiguo 07/04/2010, 14:17
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 1 mes
Puntos: 101
Respuesta: Encontrar html con expresiones regulares

Lo tengo aca:
http://www.aoi-castellano.com.ar/AoIManual/layout.php

Podes usar el menu para ver como funciona el script en las diferentes paginas. Vas a ver que en alguna funciona peor que en otras.

El script que te dejo es el que uso para imprimir el SubMenu con PHP. Es en el que me baso para evaluar resultados (aunque siempre podes hacerlo con print_r();)

Cita:
$texto = "ta ta ta ta ta ";

<?php
$patron = '/<a[^>]*>(.(?!a>))*<h[32]>.*<\/h[32]>.*<\/a>/isU'; //|<a.*>.*<h3>(.*)<\/h3>.*<\/a> // [^(<\/a>)]+
//$patron = '/<a name="(.*)">(.*)<\/a>/isU';

preg_match_all($patron, $texto, $subtitle, PREG_SET_ORDER);

for($i=0;$i<count($subtitle);$i++){
if (isset($subtitle[$i][0])){
$subtitulos[] = strip_tags(trim($subtitle[$i][0]), "<a>");
}
};
?>
<div id="submenu" class="menu">
<?php

if(isset($subtitulos)){

echo "<ul>"."\r";

$subtitulos = array_values(array_diff($subtitulos, array('')));

for($i=0;$i<count($subtitulos);$i++){

echo "<li>$subtitulos[$i]</li>"."\r";
};

echo "</ul>"."\r";
}
?>
</div>
Me encantaría que resolvamos el misterio!
  #18 (permalink)  
Antiguo 07/04/2010, 15:20
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Tokyo - Japan !
Mensajes: 3.867
Antigüedad: 14 años, 6 meses
Puntos: 334
Respuesta: Encontrar html con expresiones regulares

esta casi lista la expresion..
lee esto.. esta interesante sirve para lo que necesitas

http://tipsdeaweb.com/index.php/2007...s-y-perezosas/
__________________
More about me...
~ @rhyudek1
~ Github
  #19 (permalink)  
Antiguo 07/04/2010, 16:09
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Tokyo - Japan !
Mensajes: 3.867
Antigüedad: 14 años, 6 meses
Puntos: 334
Respuesta: Encontrar html con expresiones regulares

OMG lo logre... no me preguntes como por que no entiendo bien que hice xD
osea si pero nose en que influyen los ?:

<a([^>]*?)>(?:.(?!a>))*<h([32])>.*?</h\2>(?:.(?!a>))*</a>

ves como no me la gano (H)

saludos!
__________________
More about me...
~ @rhyudek1
~ Github
  #20 (permalink)  
Antiguo 07/04/2010, 16:23
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 1 mes
Puntos: 101
Respuesta: Encontrar html con expresiones regulares

Esta bueno. Si te fijas, yo puse unos links en donde se explica eso ?:

En mi ultimo metodo, uso ?! que es modo negación. Sirve para explicar que despues de "algo", viene o no "algo mas". http://www.codingforums.com/showthread.php?t=69898

Che, vi la pagina que posteaste. Pero en esa pagina estan confundiendo. Fijate que ponen como ejemplo esto:

$patron = '/<div>(.*)<\/div>/U';

Que devuelve:
[0] => 'esto es un ejemplo de texto</div><div> se mostrara como funcionan en modo perezoso o codicioso'.

Es decir, todo lo contrario a lo que vengo aprendiendo! Pero luego se contradicen con esto:

Cita:
php nos ofrecen el modificador U (PCRE_UNGREEDY) para poder alterar este comportamiento, haciendo que los cuantificadores que son codiciosos de manera predeterminada, se vuelvan perezosos.
Te agradezco el link. Justo hace un par de días hablabamos de esto <div>(.*?)</div> acá:

http://www.forosdelweb.com/f18/subca...ml-794191-new/
Cita:
mmm el signo ? al lado de un * no sirve de nada ya que el cuantificador * de por si solo ya condiciona la existencia o no de los caracteres!
  #21 (permalink)  
Antiguo 07/04/2010, 16:25
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Tokyo - Japan !
Mensajes: 3.867
Antigüedad: 14 años, 6 meses
Puntos: 334
Respuesta: Encontrar html con expresiones regulares

jaajaja si me acuerdo.. ahi aun no lo sabia :P.. ahora si lo se *o*

te funciono la expresion?^solo usa /is no uses U ya que los puse yo en la regex
__________________
More about me...
~ @rhyudek1
~ Github
  #22 (permalink)  
Antiguo 07/04/2010, 16:32
Avatar de mayid
Colaborador
 
Fecha de Ingreso: marzo-2009
Ubicación: BsAs
Mensajes: 4.014
Antigüedad: 15 años, 1 mes
Puntos: 101
Respuesta: Encontrar html con expresiones regulares

Sii! Funciona abriendo y cerrando con #
Cita:
$patron = '#<a([^>]*?)>(?:.(?!a>))*<h([32])>.*?</h\2>(?:.(?!a>))*</a>#';
Estas contento? Fue dificil llegar a esto!
  #23 (permalink)  
Antiguo 07/04/2010, 16:54
Colaborador
 
Fecha de Ingreso: octubre-2009
Ubicación: Tokyo - Japan !
Mensajes: 3.867
Antigüedad: 14 años, 6 meses
Puntos: 334
Respuesta: Encontrar html con expresiones regulares

siempre me gusta aprender cosas nuevas ;)
q bueno q funciono :P
__________________
More about me...
~ @rhyudek1
~ Github

Etiquetas: encontrar, expresiones, html, regulares
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 12:07.