2009-08-22 7 views
3

Il y a beaucoup de regex pour faire correspondre une URL. Cependant, j'essaye de faire correspondre des URL qui n'apparaissent nulle part dans une étiquette d'hyperlien <a> (HREF, valeur interne, etc.). Donc, aucun des URL dans ceux-ci devraient correspondre:Expression régulière pour trouver les URL ne se trouvant pas dans un lien hypertexte

 
<a href="http://www.example.com/">something</a> 
<a href="http://www.example.com/">http://www.example2.com</a> 
<a href="http://www.example.com/"><b>something</b>http://www.example.com/<span>test</span></a> 

Toute URL de l'extérieur <a></a> doit être adapté.

Une approche que j'ai essayé était d'utiliser un négatif pour voir préanalyse si la première balise <a> après l'URL est une ouverture <a> ou une fermeture </a>. Si c'est une fermeture </a> alors l'URL doit être dans un lien hypertexte. Je pense que cette idée était correcte, mais l'expression rationnelle negative n'a pas fonctionné (ou plus exactement, l'expression régulière n'a pas été écrite correctement). Tous les conseils sont très appréciés.

+0

Quelle plateforme? Perl, .NET ou Java? –

+0

duplicata possible de [Comment faire pour encapsuler du texte dans un lien hypertexte SEULEMENT si ce n'est pas déjà encapsulé dans un lien hypertexte] (http://stackoverflow.com/questions/1191637/how-to-wrap-text-in-a-hyperlink -only-if-it-isnt-déjà-enveloppé-dans-un-hyperlien) – tchrist

Répondre

2

Vous pouvez le faire en deux étapes au lieu d'essayer de trouver une seule expression régulière:

  1. Blend out (remplacer par rien), la pièce d'ancrage HTML (toute balise d'ancrage: balise d'ouverture, contenu et balise de fermeture).

  2. match l'URL

En Perl il pourrait être:

my $curLine = $_; #Do not change $_ if it is needed for something else. 
$curLine =~ /<a[^<]+<\/a>//g; #Remove all of HTML anchor tag, "<a", "</a>" and everything in between. 
if ($curLine =~ /http:\/\//) 
{ 
    print "Matched an URL outside a HTML anchor !: $_\n"; 
} 
+0

Si je supprime (fusionne) les ancres HTML, je ne serai pas en mesure de déterminer si l'URL était à l'origine dans un lien hypertexte, non? Je ne recherche que les URL en dehors des tags de lien hypertexte. –

+0

Je veux dire: enlever * tout * de l'étiquette d'ancrage d'ouverture jusqu'à l'étiquette d'ancrage de fermeture. –

+0

Ah, excellente solution. Je l'ai fait fonctionner. Au début, je pensais que vous vouliez juste enlever les balises de début et de fin, mais enlever l'étiquette entière était l'astuce. Je vous remercie!! –

0

Vous pouvez le faire en utilisant une seule expression régulière qui correspond à la fois les balises d'ancrage et hyperliens:

# Note that this is a dummy, you'll need a more sophisticated URL regex 
regex = '(<a[^>]+>)|(http://.*)' 

Puis bouclez sur les résultats et seulement les correspondances de processus où le deuxième sous-modèle a été trouvé.

+0

Cela ne fonctionne que pour les URL qui sont à l'intérieur de la balise, pas pour ceux qui se trouvent dans un élément . En outre, il essaie d'analyser un langage non régulier avec des expressions régulières. – Svante

+0

@Svante: Tout d'abord, vous pouvez facilement étendre l'exemple pour correspondre à tout dans et. Ensuite, il fait la même chose que la réponse acceptée, seulement en un seul passage. Deuxièmement, non, "ça" n'essaye pas d'analyser autre chose qu'un langage régulier basé sur des occurrences de chaînes HTML-ish. Il n'est pas nécessaire d'utiliser un analyseur HTML complet si tout ce que vous voulez est de trouver un motif simple dans la chaîne. –

0

Peter a une excellente réponse: tout d'abord, retirez les ancres de sorte que

Some text <a href="http://page.net">TeXt</a> and some more text with link http://a.net 

est remplacé par

Some text and some more text with link http://a.net 

et passons ensuite une expression rationnelle qui trouve urls:

http://a.net 
0

Utilisez les DOM pour filtrer les éléments d'ancrage, puis faire une simple regex d'URL sur le reste.

Questions connexes