2010-05-21 10 views
22

Estoy tratando de analizar una cadena y obtener múltiples fragmentos de datos de la misma cadena con las mismas expresiones regulares. Estoy analizar un único documento HTML que es estática (Por una razón no revelada, no puedo utilizar un analizador de HTML para hacer el trabajo.) Tengo una expresión que parece:¿Cómo puedo capturar varias coincidencias de la misma Perl regex?

$string =~ /\<img\ssrc\="(.*)"/; 

y quiero obtener el valor de $ 1. Sin embargo, en una cadena, hay muchas etiquetas img como esta, entonces necesito algo como una matriz devuelta (¿@ 1?) ¿Es esto posible?

+0

En estos casos, agrego más contexto a mi expresión regular para obtener la etiqueta de imagen particular que quiero. Es decir, cuando no tengo ganas de hacerlo bien utilizando un analizador HTML, como HTML :: SimpleLinkExtor, que extrae todos los valores de img src por usted. –

Respuesta

19

como la respuesta de Jim, utilice el modificador g/(en el contexto de lista o en un bucle).

Pero tenga cuidado con la codicia, no desea que el .* coincida más de lo necesario (y no escape < =, no son especiales).

while($string =~ /<img\s+src="(.*?)"/g) { 
    ... 
} 
+0

Impresionante, sí, estaba teniendo un problema con la codicia, ¿verdad? arreglado. Diga, ¿conocerá usted la lista de personajes que deben escaparse en expresiones regulares? Básicamente, escapo casi todo porque no sé mejor: P –

+0

En general, debe escapar metacaracteres y cuantificadores. En Perl tienes: 'Metacaracteres:. $^|() [] \ Cuantificadores: * +? {} ' Pero hay algunas complicaciones, en particular, dentro de una clase de personaje [] las cosas cambian. – leonbloy

+1

... pero la mejor manera de solucionar ese problema de codicia es usar '" ([^ "] *)" '. En muchos motores de expresiones regulares, esto será más eficiente, pero, más importante aún, es una declaración más clara de su intención: desea hacer coincidir "seguido de un número de caracteres * no dobles", seguido de otros ", no dos" caracteres separados por la secuencia más corta posible de * cualquier carácter *. –

2

utilizar el contexto/g modificador y lista de la izquierda, como en

@result = $string =~ /\<img\ssrc\="(.*)"/g; 
+0

Pero no tengo una serie de cadenas, solo una. Estoy tratando de obtener fuentes individuales de las etiquetas de img múltiples en la cadena única, devuelta como una matriz. Intenté esto pero no devolvió nada. –

+0

La respuesta de Robert proporciona la sintaxis correcta para este enfoque – leonbloy

+0

¿Qué crees que está haciendo el operador vinculante? :) –

5

Sólo tiene el modificador/g mundial al final del partido. Entonces bucle a través de hasta que no hay partidos restantes

my @matches; 
while ($string =~ /\<img\ssrc\="(.*)"/g) { 
     push(@matches, $1); 
} 
7
@list = ($string =~ m/\<img\ssrc\="(.*)"/g); 

El g modificador partidos todas las ocurrencias de la cadena. El contexto de la lista devuelve todas las coincidencias. Consulte el operador m // en perlop.

Cuestiones relacionadas