Estrai parte di una corrispondenza regex


131

Voglio un'espressione regolare per estrarre il titolo da una pagina HTML. Attualmente ho questo:

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

Esiste un'espressione regolare per estrarre solo il contenuto di <title> in modo da non dover rimuovere i tag?


5
wow non riesco a credere a tutte le risposte che chiamano per analizzare l'intera pagina HTML solo per estrarre un semplice titolo. Che esagerazione!
hoju

4
Domanda titolo dice tutto - l'esempio dato capita di essere HTML, ma il problema generale è ... generale.
Phil

Risposte:


209

Usa ( )in regexp e group(1)in python per recuperare la stringa catturata ( re.searchtornerà Nonese non trova il risultato, quindi non usare group()direttamente ):

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

if title_search:
    title = title_search.group(1)

1
Se non stai facendo nulla quando non viene trovato alcun titolo, perché sarebbe una cosa negativa usare direttamente group ()? (puoi comunque catturare l'eccezione)
tonfa

1
sì, ma la maggior parte delle persone dimentica le eccezioni e sono davvero sorprese quando le vedono in fase di esecuzione :)
Krzysztof Krasoń

Non dimenticare di correre, import realtrimenti otterraiNameError: name 're' is not defined
Powers

16

Nota che iniziando Python 3.8e introducendo espressioni di assegnazione (PEP 572) ( :=operatore), è possibile migliorare un po ' la soluzione di Krzysztof Krasoń catturando il risultato della corrispondenza direttamente all'interno della condizione if come variabile e riutilizzandolo nel corpo della condizione :

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

6

Prova a utilizzare l'acquisizione di gruppi:

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


4

Posso consigliarti Beautiful Soup. Soup è un'ottima libreria per analizzare tutto il tuo documento html.

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

Vorrei aggiungere che beautifulsoup analizza anche html incompleto, ed è davvero carino.
endre

3

Provare:

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

Se vuoi davvero usare REGEX per l'analisi HTML, non eseguire .group () direttamente sulla corrispondenza, poiché potrebbe restituire None.
iElectric

Dovresti usare .*?così nel caso ce ne siano più </title>nel documento (improbabile ma non si sa mai).
tonfa

@iElectric: potresti metterlo in una prova tranne che in blocco se vuoi davvero, giusto?
tonfa

3

I pezzi di codice forniti non si adattano a Exceptions May I suggerire

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

Questo restituisce una stringa vuota per impostazione predefinita se il modello non è stato trovato o la prima corrispondenza.


1

Penso che questo dovrebbe essere sufficiente:

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

... supponendo che il tuo testo (HTML) sia in una variabile denominata "testo".

Ciò presuppone anche che non ci siano altri tag HTML che possono essere incorporati legalmente all'interno di un tag HTML TITLE e non c'è modo di incorporare legalmente qualsiasi altro carattere <all'interno di tale contenitore / blocco.

però ...

Non utilizzare espressioni regolari per l'analisi HTML in Python. Usa un parser HTML! (A meno che tu non voglia scrivere un parser completo, che sarebbe un lavoro extra quando vari parser HTML, SGML e XML sono già nelle librerie standard.

Se stai gestendo tag "del mondo reale" in HTML (che spesso non è conforme a qualsiasi validatore SGML / XML) allora usa BeautifulSoup pacchetto . Non è (ancora) nelle librerie standard ma è ampiamente consigliato per questo scopo.

Un'altra opzione è: lxml ... che è scritto per HTML adeguatamente strutturato (conforme agli standard). Ma ha un'opzione per ripiegare sull'uso di BeautifulSoup come parser: ElementSoup .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.