2009-08-18 8 views
1

Je cherche un modèle d'expression régulière qui pourrait correspondre à des URL en HTML qui ne sont pas enveloppées dans une balise 'a', afin de les envelopper dans 'a' plus loin (c'est-à-dire mettre en surbrillance tous les liens non mis en évidence).Correspond à toutes les URL qui ne sont pas enveloppées dans <a> tag

L'entrée est du HTML simple avec les balises 'a', 'b', 'i', 'br', 'p' 'img' autorisées. Toutes les autres balises HTML ne doivent pas apparaître dans l'entrée, mais les balises mentionnées ci-dessus peuvent apparaître dans toutes les combinaisons. Donc, pattern doit omettre toutes les URLs qui font partie des balises 'a' existantes, et faire correspondre tous les autres liens qui ne sont que du texte brut et qui ne sont pas mis en évidence et ne sont pas encore des hyperliens. Il serait bon que le modèle corresponde aux URL commençant par http: //, https: // ou www., Et se terminant par .net, .com. ou .org si l'URL ne commence pas par http: //, https: // ou www.

J'ai essayé quelque chose comme '(?! < [aA] [^>] +>) http://[a-zA-Z0-9._-]+ (?!)' Pour correspondre à un cas plus simple que celui décrit ci-dessus, mais il semble que cette tâche ne soit pas évident.

Merci beaucoup pour toute aide.

Répondre

5

Vous pouvez utiliser BeautifulSoup ou similaire pour exclure toutes les URL faisant déjà partie de liens.

Ensuite, vous pouvez faire correspondre le texte brut avec l'une des expressions régulières url qui existe déjà (google "expression régulière url", celui que vous voulez dépend de la fantaisie que vous voulez obtenir).

+1

+1 pour suggérer BeautifulSoup. Ce problème n'est pas bien adapté à une solution regex pure. –

5

Parsing HTML avec une seule regex est presque impossible par définition, puisque les expressions régulières n'ont pas d'état.

Construire/Utiliser un analyseur réel à la place. Peut-être BeautifulSoup ou html5lib.

Ce code ci-dessous utilise BeautifulSoup pour extraire tous les liens de la page:

from BeautifulSoup import BeautifulSoup 
from urllib2 import urlopen 

url = 'http://stackoverflow.com/questions/1296778/' 
stream = urlopen(url) 
soup = BeautifulSoup(stream) 
for link in soup.findAll('a'): 
    if link.has_key('href'): 
     print unicode(link.string), '->', link['href'] 

De même que vous pourriez trouver tout le texte en utilisant soup.findAll(text=True) et rechercher des urls là-bas.

La recherche d'URL est également très complexe - vous ne croiriez pas sur ce qui est autorisé sur une URL. Une simple recherche montre des milliers d'exemples, mais aucun ne correspond exactement aux spécifications. Vous devriez essayer ce qui fonctionne mieux pour vous.

-2

Merci les gars! Voici ma solution:

from django.utils.html import urlize # Yes, I am using Django's urlize to do all dirty work :) 

def urlize_html(value): 
    """ 
    Urlizes text containing simple HTML tags. 
    """ 
    A_IMG_REGEX = r'(<[aA][^>]+>[^<]+</[aA]>|<[iI][mM][gG][^>]+>)' 
    a_img_re = re.compile(A_IMG_REGEX) 

    TAG_REGEX = r'(<[a-zA-Z]+[^>]+>|</[a-zA-Z]>)' 
    tag_re = re.compile(TAG_REGEX) 

    def process(s, p, f): 
     return "".join([c if p.match(c) else f(c) for c in p.split(s)]) 

    def process_urlize(s): 
     return process(s, tag_re, urlize) 

    return process(value, a_img_re, process_urlize) 
+0

Je n'ai pas besoin de trop réfléchir pour créer un code HTML qui ferait échouer. – nosklo

Questions connexes