Pregunta

Estoy escribiendo una función que extrae el src de la primera etiqueta de imagen que encuentra en un archivo html. Siguiendo las instrucciones en este hilo aquí, obtuve algo que parecía estar funcionando:

preg_match_all('#<img[^>]*>#i', $content, $match); 

foreach ($match as $value) {
    $img = $value[0];
                           } 

$stuff = simplexml_load_string($img);
$stuff = $stuff[src];
return $stuff;

Pero después de unos minutos de usar la función, comenzó a devolver errores como este:

  

advertencia: simplexml_load_string () [0function.simplexml-load-string0]: Entidad: línea 1: error del analizador: Fin prematuro de datos en etiqueta img línea 1 en ruta / a / script en la línea 42.

y

  

advertencia: simplexml_load_string () [0function.simplexml-load-string0]: tp: //feeds.feedburner.com/~f/ChicagobusinesscomBreakingNews? i = KiStN " border = " 0 " > en ruta / a / script en la línea 42.

Soy un poco nuevo en PHP, pero parece que mi expresión regular está cortando incorrectamente el HTML. ¿Cómo puedo hacerlo más "hermético"?

¿Fue útil?

Solución

Estas dos líneas de código PHP deberían darle una lista de todos los valores del atributo src en todas las etiquetas img en un archivo HTML:

preg_match_all('/<img\s+[^<>]*src=["\']?([^"\'<>\s]+)["\']?/i', $content, $result, PREG_PATTERN_ORDER);
$result = $result[1];

Para mantener la expresión regular simple, no estoy permitiendo que los nombres de archivo tengan espacios en ellos. Si desea permitir esto, debe usar alternativas separadas para los valores de atributo entre comillas (que pueden tener espacios) y los valores de atributo sin comillas (que no pueden tener espacios).

Otros consejos

Probablemente porque el " XML " ser recogido por la expresión regular no es un XML adecuado por cualquier razón. Probablemente optaría por una expresión regular más complicada que eliminaría el atributo src, en lugar de usar SimpleXML para obtener el src. Este REGEX podría estar cerca de lo que necesita.

<img[^>]*src\s*=\s*['|"]?([^>]*?)['|"]?[^>]*>

También podría usar una biblioteca de análisis HTML real, pero no estoy seguro de qué opciones existen en PHP.

Un ampersand en sí mismo en un atributo es XML no válido (debe codificarse como & # 8220; & amp; amp; & # 8221;), pero algunas personas todavía lo expresan de esa manera en las URL en las páginas HTML (y en todos los navegadores) apoyarlo). Tal vez ahí radica tu problema.

Si ese es el caso, puede desinfectar su cadena antes de analizarla, sustituyendo & # 8220; & amp; (?! amp;) & # 8221; por & # 8220; & amp; amp; & # 8221 ;.

Sobre un tema diferente:

foreach ($match as $value) {
    $img = $value[0];
                           } 

se puede reemplazar con

$img = $match[count($match) - 1][0];

Algo como esto:

if (preg_match('#<img\s[^>]*>#i', $content, $match)) {
    $img = $match[0]; //first image in file only
    $stuff = simplexml_load_string($img);
    $stuff = $stuff[src];
    return $stuff;
} else {
    return null; //no match found
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top