Regex para analisar hiperlinks e descrições
Pergunta
C#:O que é um bom Regex para analisar hiperlinks e suas descrições?
Considere a insensibilidade entre maiúsculas e minúsculas, espaços em branco e o uso de aspas simples (em vez de aspas duplas) ao redor da tag HREF.
Considere também obter hiperlinks que contenham outras tags dentro do <a>
tags como <b>
e <i>
.
Solução
Contanto que não haja tags aninhadas (e nenhuma quebra de linha), a seguinte variante funciona bem:
<a\s+href=(?:"([^"]+)"|'([^']+)').*?>(.*?)</a>
Assim que as tags aninhadas entram em ação, as expressões regulares ficam impróprias para análise.No entanto, você ainda pode usá-los aplicando recursos mais avançados de intérpretes modernos (dependendo da sua máquina regex).Por exemplo.As expressões regulares do .NET usam uma pilha;Eu achei isto:
(?:<a.*?href=[""'](?<url>.*?)[""'].*?>)(?<name>(?><a[^<]*>(?<DEPTH>)|</a>(?<-DEPTH>)|.)+)(?(DEPTH)(?!))(?:</a>)
Fonte: http://weblogs.asp.net/scottcate/archive/2004/12/13/281955.aspx
Outras dicas
Veja este exemplo de StackOverflow:Expressão regular para analisar links de uma página da web?
Usando O pacote de agilidade HTML você pode analisar o HTML e extrair detalhes usando a semântica do HTML, em vez de um regex quebrado.
Eu achei isto mas aparentemente esses caras teve alguns problemas com isso.
Editar: (Funciona!)
Agora fiz meus próprios testes e descobri que funciona, não conheço C#, então não posso lhe dar uma resposta em C#, mas conheço PHP e aqui está o array de correspondências que recebi ao executá-lo:
<a href="pages/index.php" title="the title">Text</a>
array(3) { [0]=> string(52) "Text" [1]=> string(15) "pages/index.php" [2]=> string(4) "Text" }
EU tem uma regex que lida com a maioria dos casos, embora eu acredite que corresponda ao HTML em um comentário de várias linhas.
Foi escrito usando a sintaxe .NET, mas deve ser facilmente traduzível.
Só vou lançar esse trecho agora que estou funcionando. Esta é uma versão menos gananciosa da sugerida anteriormente.O original não funcionaria se a entrada tivesse vários hiperlinks.O código abaixo permitirá que você percorra todos os hiperlinks:
static Regex rHref = new Regex(@"<a.*?href=[""'](?<url>[^""^']+[.]*?)[""'].*?>(?<keywords>[^<]+[.]*?)</a>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
public void ParseHyperlinks(string html)
{
MatchCollection mcHref = rHref.Matches(html);
foreach (Match m in mcHref)
AddKeywordLink(m.Groups["keywords"].Value, m.Groups["url"].Value);
}
Aqui está uma expressão regular que corresponderá às tags balanceadas.
(?:""'[""'].*?>)(?(?>(?)|(?<-PROFUNDIDADE>)|.)+)(?(PROFUNDIDADE)(?!))(?: )