Índice de la sección dedicada a .NET (en el Guille) Expresiones Regulares

Extraer la dirección de un link HTML
Con ejemplo de cómo usarlo con VB .NET y C#

Publicado el 08/Ene/2004
Actualizado el 08/Ene/2004


Por ejemplo, si vamos a analizar un fichero HTML y nos interesan todos los links que haya, los cuales estarán de esta forma: <a href="dirección web o link">Lo que sea...</a>
podemos usar el siguiente código para extraer la dirección indicada después de href=:
<a href=\s*([^>]*)

La explicación:

Veamos la cadena por trozos:

<a href= esto simplemente indica que queremos buscar desde donde estén estas palabras, aquí no hay nada "mágico"
\s* Esto indica que puede haber cualquier cantidad de espacios en blanco (espacios, tabuladores...)
El \s indica cualquier espacio blanco y el * indica cualquier cantidad.
[^>]* Esto significa cualquier cosa que haya hasta encontrar el signo >, o lo que es lo mismo todo lo que no sea el signo >, ya que [^ significa que no se tendrá en cuenta lo que haya hasta el siguiente ]
El * como antes significa que se puede repetir eso las veces que sea necesario, es decir, se tomarán todos los caracteres distintos de >, en cuanto se encuentre con un > se dejará de "buscar".
() Los paréntesis indican que lo que se encuentre por medio de ese "comando" se agrupe, es decir, se guardará aparte para que podamos extraerlo, en el código veremos cómo.
Si no usáramos los paréntesis, lo que se encuentre no se conserva para su posterior uso.

Esa sería la expresión regular "simple" y funcionará siempre y cuando todo esté en la misma línea, pero si por ejemplo el final del href, es decir el > está en otra línea... también se incluiría el retorno de carro y demás espacios en blanco que hubiera.
Por ejemplo, si el código que analizamos incluye esto:

<p>Esto es una prueba <a href='http://www.elguille.info/'
    ">el Guille</a> Más cosas.<br>

Esto es una prueba <a href='http://www.elguille.info/NET/indice.asp'  >La sección .NET en el Guille</a> Más cosas.</p>

Los espacios en  blanco que hay después de los links (y el cambio de línea) también se incluiría en el resultado de la búsqueda, ya que al fin y al cabo está antes del signo >.

Si no queremos esos espacios extras, ni el cambio de línea, podemos usar esta otra expresión regular:
<a href=\s*([^\s]*)\s*>

En este caso, el \s que hay dentro del corchete indicará que debemos tomar todo hasta el primer espacio en "blanco", (esto está bien si la URL no incluye espacios en blanco, cosa que no es recomendable).
Por otro lado, el \s*> que hay después del paréntesis indica que debemos ignorar cualquier cantidad de espacios en blanco, (recuerda que los espacios en blanco incluyen los tabuladores, etc.), y un >.
Por tanto, si tenemos la cadena anterior, ahora sólo se obtendrá lo que hay después del signo igual y hasta el primer espacio en blanco, es decir: la dirección URL que queríamos.


Añadido después de la publicación original:

Si quieres tener sólo la dirección (el link), sin incluir las comillas entre las que se suele encerrar, puedes usar este otro código:

"<a href=\s*[""']([^\s]*)[""']\s*>"

Aquí se tiene en cuenta que la dirección esté entre comillas dobles o simples.
Para C#, sin usar @ delante de la cadena, tendrás que usar este otro:

"<a href=\\s*[\"']([^\\s]*)[\"']\\s*>"
 

 

Aquí tienes un ejemplo para usar tanto en Visual Basic .NET como en C#.
En ambos casos, habrá que hacer una importación del espacio de nombres:
System.Text.RegularExpressions

El código de Visual Basic .NET

Dim r As Regex
Dim s As String
Dim m As Match
'
' para extraer links:
s = "<p>Esto es una prueba <a href='http://www.elguille.info/'     " & vbCrLf & ">el Guille</a> Más cosas." & vbCrLf & _
"Esto es una prueba <a href='http://www.elguille.info/NET/indice.asp' >La sección .NET en el Guille</a> Más cosas.</p>" r = New Regex("<a href=\s*([^\s]*)\s*>")
Dim mc As MatchCollection = r.Matches(s)
If mc.Count > 0 Then
Console.WriteLine("¡BINGO! hay {0} coincidencias", mc.Count)
For Each m In mc
Console.WriteLine("0= |{0}|", m.Result("$0"))
Console.WriteLine("1= |{0}|", m.Result("$1"))
Next
Else
Console.WriteLine("¡Sin coincidencias!")
End If

Con m.Result("$1") conseguimos el link.
En m.Result("$0") tendremos todo, desde <a href hasta el > del final.

 

El código de C#

string s;
Regex r;
//
s = @"<p>Esto es una prueba <a href='http://www.elguille.info/'     " + '\n' + ">el Guille</a> Más cosas.<br>" + '\n' +
    "Esto es una prueba <a href='http://www.elguille.info/NET/indice.asp'   >La sección .NET en el Guille</a> Más cosas.</p>";
//r = new Regex("<a href=\\s*([^\\s]*)\\s*>");
r = new Regex(@"<a href=\s*([^\s]*)\s*>");
//
MatchCollection mc = r.Matches(s);
if( mc.Count > 0)
{
    Console.WriteLine("¡BINGO! hay {0} coincidencias", mc.Count);
    foreach(Match m in mc)
    {
        Console.WriteLine("0= |{0}|", m.Result("$0"));
        Console.WriteLine("1= |{0}|", m.Result("$1"));
    }
}
else
    Console.WriteLine("No hay coincidencias.");

En C# hay que tener cuidado con las barras \ ya que dentro de una cadena se interpretan como códigos de escape, por tanto o bien usamos dos seguidas o bien indicamos al principio @ para que no se interprete ningún código de escape.

 

Espero que ya sepas algo más de cómo usar las expresiones regulares.

Nos vemos.
Guillermo



Volver a las Expresiones Regulares

la Luna del Guille o... el Guille que está en la Luna... tanto monta...