web-dev-qa-db-fra.com

Extraire une partie d'un match regex

Je veux une expression régulière pour extraire le titre d'une page HTML. Actuellement j'ai ceci:

title = re.search('<title>.*</title>', html, re.IGNORECASE).group()
if title:
    title = title.replace('<title>', '').replace('</title>', '') 

Existe-t-il une expression régulière pour extraire uniquement le contenu de <title> afin que je n’aie pas à supprimer les balises?

94
hoju

Utilisez () Dans l’expression rationnelle et group(1) dans python pour récupérer la chaîne capturée ( re.search retournera None s'il ne trouve pas le résultat, aussi n'utilise pas group() directement ):

title_search = re.search('<title>(.*)</title>', html, re.IGNORECASE)

if title_search:
    title = title_search.group(1)
143
Krzysztof Krasoń

Merci de ne PAS utiliser regex pour analyser les langages de balisage. Utilisez lxml ou beautifulsoup.

37
iElectric

Essayez d’utiliser des groupes de capture:

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)
6
Aaron Maenpaa

re.search('<title>(.*)</title>', s, re.IGNORECASE).group(1)

3
Vinay Sajip

Les morceaux de code fournis ne traitent pas Exceptions Puis-je suggérer

getattr(re.search(r"<title>(.*)</title>", s, re.IGNORECASE), 'groups', lambda:[u""])()[0]

Cela retourne une chaîne vide par défaut si le motif n'a pas été trouvé ou la première correspondance.

3
Steve K

Notez que partir de Python 3.8, et l'introduction de expressions d'affectation (PEP 572) (:= opérateur), il est possible d’améliorer un peu solution de Krzysztof Krasoń en capturant le résultat du match directement dans la condition if en tant que variable et en le réutilisant dans le corps de la condition:

# pattern = '<title>(.*)</title>'
# text = '<title>hello</title>'
if match := re.search(pattern, text, re.IGNORECASE):
  title = match.group(1)
# hello
3
Xavier Guihot

Essayer:

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)
2
Randy

Puis-je vous recommander de belle soupe. Soup est une très bonne bibliothèque pour analyser tout votre document HTML.

soup = BeatifulSoup(html_doc)
titleName = soup.title.name
2
kharagpur

Je pense que cela devrait suffire:

#!python
import re
pattern = re.compile(r'<title>([^<]*)</title>', re.MULTILINE|re.IGNORECASE)
pattern.search(text)

... en supposant que votre texte (HTML) se trouve dans une variable nommée "texte".

Cela suppose également qu’il n’y ait pas d’autres balises HTML pouvant être légalement incorporées dans une balise HTML TITLE et qu’il n’ya aucun moyen d’incorporer légalement un autre caractère <dans un tel conteneur/bloc.

Cependant ...

N'utilisez pas d'expressions régulières pour l'analyse HTML en Python. Utilisez un analyseur HTML! (À moins que vous n'écriviez un analyseur complet, ce qui représenterait un travail supplémentaire lorsque divers analyseurs HTML, SGML et XML figurent déjà dans les bibliothèques standard.

Si vous manipulez le "monde réel" comme balise soupe HTML (qui est souvent non conforme à un validateur SGML/XML), utilisez le BeautifulSoup) package. Ce n'est pas (encore) dans les bibliothèques standard mais est largement recommandé à cet effet.

Une autre option est: lxml ... qui est écrit pour du code HTML correctement structuré (conforme aux normes). Mais il est possible de recourir à BeautifulSoup en tant qu’analyseur: ElementSoup .

1
Jim Dennis