Trích xuất một phần của trận đấu regex


130

Tôi muốn một biểu thức chính quy để trích xuất tiêu đề từ trang HTML. Hiện tại tôi có cái này:

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

Có một biểu thức chính quy để chỉ trích xuất nội dung của <title> vì vậy tôi không phải xóa các thẻ?


5
wow Tôi không thể tin tất cả các phản hồi kêu gọi phân tích toàn bộ trang HTML chỉ để trích xuất một tiêu đề đơn giản. Những gì quá mức cần thiết!
hoju

4
Tiêu đề câu hỏi nói lên tất cả - ví dụ đưa ra là HTML, nhưng vấn đề chung là ... chung chung.
Phil

Câu trả lời:


207

Sử dụng ( )trong regrec và group(1)python để lấy chuỗi đã bắt ( re.searchsẽ trả về Nonenếu nó không tìm thấy kết quả, vì vậy đừng sử dụng group()trực tiếp ):

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

if title_search:
    title = title_search.group(1)

1
Nếu bạn không làm gì khi không tìm thấy tiêu đề, tại sao việc sử dụng trực tiếp nhóm () sẽ là một điều xấu? (dù sao bạn cũng có thể bắt ngoại lệ)
tonfa

1
vâng, nhưng hầu hết mọi người quên đi các ngoại lệ, và thực sự ngạc nhiên khi họ nhìn thấy chúng trong thời gian chạy :)
Krzysztof Krasnoy Kras

Đừng quên chạy import renếu không bạn sẽ nhận đượcNameError: name 're' is not defined
Powers

16

Lưu ý rằng bắt đầu Python 3.8và giới thiệu các biểu thức gán (PEP 572) ( :=toán tử), có thể cải thiện một chút về giải pháp của Krzysztof Krasnoy bằng cách chụp trực tiếp kết quả khớp trong điều kiện if như một biến và sử dụng lại nó trong cơ thể của điều kiện :

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

6

Hãy thử sử dụng các nhóm chụp:

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


4

Tôi có thể giới thiệu bạn với Soup đẹp. Soup là một lib rất tốt để phân tích tất cả các tài liệu html của bạn.

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

Tôi muốn nói thêm rằng, beautifulsoup cũng phân tích cú pháp html không hoàn chỉnh và điều đó thực sự tốt.
thúc vào

3

Thử:

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

Nếu bạn thực sự muốn sử dụng REGEX để phân tích cú pháp HTML, đừng chạy trực tiếp .group () vì nó có thể trả về Không.
iElectric

Bạn nên sử dụng .*?như vậy trong trường hợp có nhiều </title>tài liệu (không chắc nhưng bạn không bao giờ biết).
tonfa

@iElectric: bạn có thể đặt nó trong một thử ngoại trừ khối nếu bạn thực sự muốn, phải không?
tonfa

3

Các đoạn mã được cung cấp không phù hợp với Exceptions tháng 5 tôi đề nghị

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

Điều này trả về một chuỗi rỗng theo mặc định nếu không tìm thấy mẫu hoặc khớp đầu tiên.


1

Tôi nghĩ rằng điều này nên đủ:

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

... giả sử rằng văn bản của bạn (HTML) nằm trong một biến có tên là "văn bản".

Điều này cũng giả định rằng không có các thẻ HTML khác có thể được nhúng hợp pháp bên trong thẻ HTML TITLE và không có cách nào để nhúng hợp pháp bất kỳ <ký tự nào khác trong một thùng / khối như vậy.

Tuy nhiên ...

Đừng sử dụng các biểu thức thông thường để phân tích cú pháp HTML trong Python. Sử dụng trình phân tích cú pháp HTML! (Trừ khi bạn sẽ viết một trình phân tích cú pháp đầy đủ, đây sẽ là một công việc bổ sung khi các trình phân tích cú pháp HTML, SGML và XML khác nhau đã có trong các thư viện chuẩn.

Nếu thẻ HTML xử lý "thế giới thực" của bạn (thường không tuân thủ bất kỳ trình xác thực SGML / XML nào) thì hãy sử dụng gói BeautifulSoup . Nó không có trong các thư viện tiêu chuẩn (chưa) nhưng được khuyến nghị rộng rãi cho mục đích này.

Một tùy chọn khác là: lxml ... được viết cho HTML có cấu trúc đúng (tuân thủ tiêu chuẩn). Nhưng nó có một tùy chọn để sử dụng BeautifulSoup làm trình phân tích cú pháp: ElementSoup .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.