Ekstrak bagian dari pencocokan regex

131

Saya ingin ekspresi reguler mengekstrak judul dari halaman HTML. Saat ini saya memiliki ini:

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

Apakah ada ekspresi reguler untuk mengekstrak hanya konten <title> jadi saya tidak perlu menghapus tag?

hoju
sumber
5
wow Saya tidak percaya semua tanggapan yang memanggil untuk mengurai seluruh halaman HTML hanya untuk mengekstrak judul sederhana. Benar-benar berlebihan!
hoju
4
Judul pertanyaan mengatakan itu semua - contoh yang diberikan kebetulan HTML, tetapi masalah umumnya adalah ... umum.
Phil

Jawaban:

209

Gunakan ( )di regexp dan group(1)di python untuk mengambil string yang ditangkap ( re.searchakan dikembalikan Nonejika tidak menemukan hasilnya, jadi jangan gunakan group()secara langsung ):

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

if title_search:
    title = title_search.group(1)
Krzysztof Krasoń
sumber
1
Jika Anda tidak melakukan apa pun saat tidak ada judul yang ditemukan, mengapa hal buruk menggunakan group () secara langsung? (Anda tetap dapat melihat pengecualiannya)
tonfa
1
ya, tetapi kebanyakan orang melupakan tentang pengecualian, dan sangat terkejut ketika mereka melihatnya saat runtime :)
Krzysztof Krasoń
Jangan lupa untuk berlari import reatau Anda akan mendapatkanNameError: name 're' is not defined
Powers
16

Perhatikan bahwa memulai Python 3.8, dan pengenalan ekspresi tugas (PEP 572) ( :=operator), dimungkinkan untuk sedikit meningkatkan solusi Krzysztof Krasoń dengan menangkap hasil pertandingan langsung dalam kondisi if sebagai variabel dan menggunakannya kembali dalam tubuh kondisi :

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

Coba gunakan grup penangkapan:

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)
Aaron Maenpaa
sumber
5
re.search('<title>(.*)</title>', s, re.IGNORECASE).group(1)
Vinay Sajip
sumber
4

Izinkan saya merekomendasikan Anda untuk Beautiful Soup. Soup adalah lib yang sangat bagus untuk mengurai semua dokumen html Anda.

soup = BeatifulSoup(html_doc)
titleName = soup.title.name
kharagpur.dll
sumber
Saya ingin menambahkan, beautifulsoup itu juga mem-parsing html yang tidak lengkap, dan itu sangat bagus.
berakhir
3

Mencoba:

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)
Randy
sumber
Jika Anda benar-benar ingin menggunakan REGEX untuk penguraian HTML, jangan jalankan .group () secara langsung pada pertandingan, karena mungkin mengembalikan None.
iElectric
Anda harus menggunakannya .*?jika ada beberapa </title>dalam dokumen (tidak mungkin tetapi Anda tidak pernah tahu).
tonfa
@iElectric: Anda dapat mencobanya kecuali blok jika Anda benar-benar ingin, bukan?
tonfa
3

Potongan kode yang disediakan tidak sesuai dengan Exceptions Boleh saya sarankan

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

Ini mengembalikan string kosong secara default jika pola belum ditemukan, atau kecocokan pertama.

Steve K
sumber
1

Saya pikir ini sudah cukup:

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

... dengan asumsi bahwa teks Anda (HTML) ada dalam variabel bernama "teks".

Ini juga mengasumsikan bahwa tidak ada tag HTML lain yang dapat disematkan secara legal di dalam tag HTML TITLE dan tidak ada cara untuk menyematkan karakter <lainnya secara legal di dalam penampung / blok tersebut.

Namun ...

Jangan gunakan ekspresi reguler untuk penguraian HTML dengan Python. Gunakan pengurai HTML! (Kecuali jika Anda akan menulis parser lengkap, yang akan menjadi pekerjaan ekstra ketika berbagai parser HTML, SGML dan XML sudah ada di pustaka standar.

Jika Anda menangani HTML sup tag "dunia nyata" (yang sering kali tidak sesuai dengan validator SGML / XML apa pun), gunakan paket BeautifulSoup . Ini tidak ada di pustaka standar (belum) tetapi sangat direkomendasikan untuk tujuan ini.

Pilihan lainnya adalah: lxml ... yang ditulis untuk HTML yang terstruktur dengan benar (sesuai standar). Tetapi ia memiliki opsi untuk kembali menggunakan BeautifulSoup sebagai parser: ElementSoup .

Jim Dennis
sumber