Làm cách nào để phân tích cú pháp trang HTML bằng biểu thức chính quy?

/gis;

"Nhưng nó đã có tác dụng. " họ nói

"Dễ thôi. "

"Thật nhanh. "

"Nó sẽ làm tốt công việc. "

Tôi mắng họ vì đã không lười biếng. Bạn cần phải lười biếng như một lập trình viên. Phân tích cú pháp HTML là một vấn đề đã được giải quyết. Bạn không cần phải giải nó. Bạn chỉ cần lười biếng. Hãy lười biếng, sử dụng CPAN và sử dụng HTML. chất khử trùng. Nó sẽ làm cho mã của bạn dễ dàng hơn. Nó sẽ giúp mã của bạn dễ bảo trì hơn. Bạn sẽ không phải ngồi đó code thủ công các biểu thức chính quy. Mã của bạn sẽ mạnh mẽ hơn. Bạn sẽ không phải sửa lỗi mỗi khi HTML phá vỡ biểu thức chính quy tồi tệ của bạn

Đối với nhiều lập trình viên mới làm quen, có điều gì đó hấp dẫn lạ thường khi phân tích cú pháp HTML theo cách Cthulhu thay vì, bạn biết đấy, sử dụng thư viện như một người tỉnh táo. Điều đó có nghĩa là cuộc thảo luận này được mở lại hầu như mỗi ngày trên Stack Overflow. Bài đăng trên từ năm năm trước có thể là một cuộc thảo luận từ ngày hôm qua. Tôi nghĩ chúng ta có thể tha thứ cho sự thiếu lý trí nhất thời trong hoàn cảnh

Như tôi đã nói, đây là một hiện tượng được hiểu rõ trong hầu hết các giới lập trình. Tuy nhiên, tôi rất ngạc nhiên khi thấy một số lập trình viên có kinh nghiệm trong các nhận xét về bộ lọc siêu dữ liệu thực sự bảo vệ việc sử dụng các biểu thức chính quy để phân tích cú pháp HTML. Ý tôi là, họ đã chú ý đến Tiếng gọi của Cthulhu… và thích nó

Nhiều chương trình sẽ không cần và cũng không nên đoán trước toàn bộ thế giới HTML khi phân tích cú pháp. Trên thực tế, việc thiết kế một chương trình để làm như vậy có thể là một cách tiếp cận hoàn toàn sai lầm, nếu nó thay đổi một chương trình từ một tập lệnh vài dòng sang một chương trình cấp độ thương mại chống đạn, cần nhiều thời gian hơn để viết mã đúng cách và . Chi tiêu tài nguyên luôn phải được xem xét (rất tiếc, hãy thực hiện điều đó rất thường xuyên, tôi cũng nói về việc tổng quát hóa quá mức) khi tạo giải pháp có lập trình

Ngoài ra, ranh giới cứng không phải lúc nào cũng là giới hạn theo định hướng HTML. Chúng có thể đơn giản như "làm việc với các bộ trang web này", "làm việc với dữ liệu này từ các trang web này", "làm việc cho 98% người dùng trong 98% thời gian" hoặc thậm chí "OMG, chúng ta phải làm điều này

Chúng ta đang sống trong một thế giới đầy rẫy các nhà phát triển PHP mới làm điều đầu tiên nảy ra trong đầu họ, với nhiều người được sinh ra mỗi ngày. Những gì chúng ta có ở đây là một vấn đề giáo dục đang diễn ra. Kẻ thù thực sự không phải là biểu thức thông thường (hoặc, đối với vấn đề đó, goto), mà là sự thiếu hiểu biết. Tội ác duy nhất được gây ra là không biết những lựa chọn thay thế là gì

Vì vậy, mặc dù tôi có thể cố gắng phân tích cú pháp HTML bằng cách sử dụng các biểu thức chính quy trong một số trường hợp nhất định, nhưng tôi biết rằng

  • Đó thường là một ý tưởng tồi
  • Trừ khi bạn có kỷ luật và đặt ra những điều kiện rất nghiêm ngặt đối với những gì bạn đang làm, còn không thì việc kết hợp HTML với các biểu thức chính quy sẽ nhanh chóng trở nên điên rồ, đúng như cách mà Cthulhu thích.
  • Tôi đã có những lý do mà tôi nghĩ là tốt, hợp lý, (bán) có thể bảo vệ được để chọn biểu thức chính quy trong tình huống cụ thể này

Việc yêu cầu các biểu thức chính quy được coi là chi tiết, hoàn toàn vượt quá giới hạn để xử lý HTML, nhưng tôi nghĩ điều đó cũng sai lầm giống như việc yêu cầu mọi tác vụ xử lý HTML tầm thường phải được xử lý bởi một công cụ phân tích cú pháp toàn diện. Điều quan trọng là phải hiểu các công cụ, điểm mạnh và điểm yếu của chúng, hơn là khuất phục trước chủ nghĩa giáo điều.

Vì vậy, vâng, nói chung, không nên sử dụng các biểu thức chính quy khi phân tích cú pháp HTML. Chúng ta nên dạy cho các nhà phát triển mới vào nghề rằng, hoàn toàn. Mặc dù đó là một công việc dường như vô tận. Nhưng chúng ta cũng nên dạy cho họ sự khác biệt thực sự giữa phân tích cú pháp HTML và thủ thuật đơn giản là xử lý một vài chuỗi. Và làm thế nào để biết đâu là cách tiếp cận phù hợp cho nhiệm vụ hiện tại

Tại sao bạn không thể phân tích cú pháp HTML bằng regex?

Regex không phù hợp để phân tích cú pháp HTML vì HTML không phải là ngôn ngữ thông thường . Regex có lẽ sẽ không phải là công cụ để tiếp cận khi phân tích mã nguồn.

Làm cách nào để phân tích cú pháp mã HTML?

Phân tích cú pháp HTML liên quan đến xây dựng cây và tạo mã thông báo . Mã thông báo HTML bao gồm thẻ bắt đầu và thẻ kết thúc, cũng như tên và giá trị thuộc tính. Nếu tài liệu được định dạng tốt, việc phân tích cú pháp sẽ đơn giản và nhanh hơn. Trình phân tích cú pháp phân tích cú pháp đầu vào được mã hóa vào tài liệu, xây dựng cây tài liệu.

Bạn có thể sử dụng regex trong tài liệu HTML không?

Các biểu thức chính quy HTML có thể được sử dụng để tìm các thẻ trong văn bản, trích xuất hoặc xóa chúng

Bạn có thể phân tích cú pháp regex bằng regex không?

Toán tử Parse Regex (còn được gọi là toán tử trích xuất) cho phép người dùng cảm thấy thoải mái với cú pháp biểu thức chính quy để trích xuất dữ liệu phức tạp hơn từ các dòng nhật ký . Parse regex có thể được sử dụng, ví dụ, để trích xuất các trường lồng nhau.

HTML/XML được chia thành đánh dấu và nội dung. Regex chỉ hữu ích khi thực hiện phân tích cú pháp thẻ từ vựng. Tôi đoán bạn có thể suy ra nội dung. Nó sẽ là một lựa chọn tốt cho trình phân tích cú pháp SAX. Các thẻ và nội dung có thể được gửi đến một chức năng do người dùng xác định, nơi có thể theo dõi việc lồng/đóng các phần tử

Đối với việc phân tích cú pháp các thẻ, nó có thể được thực hiện bằng regex và được sử dụng để tách các thẻ khỏi tài liệu

Qua nhiều năm thử nghiệm, tôi đã tìm ra bí mật về cách trình duyệt phân tích cú pháp các thẻ, cả ở dạng tốt và dạng xấu

Các yếu tố bình thường được phân tích cú pháp với hình thức này

Cốt lõi của các thẻ này sử dụng biểu thức chính quy này

 (?:
      " [\S\s]*? " 
   |  ' [\S\s]*? ' 
   |  [^>]? 
 )+

Bạn sẽ nhận thấy điều này [^>]? là một trong những lựa chọn thay thế. Điều này sẽ khớp với các trích dẫn không cân bằng từ các thẻ không đúng định dạng

Nó cũng là gốc rễ duy nhất của mọi tội ác đối với các biểu thức thông thường. Cách nó được sử dụng sẽ kích hoạt một cú va chạm để đáp ứng thùng chứa được định lượng phải phù hợp, tham lam của nó

Nếu được sử dụng một cách thụ động, sẽ không bao giờ có vấn đề gì. Tuy nhiên, nếu bạn buộc một thứ gì đó phải khớp bằng cách xen kẽ nó với một cặp thuộc tính/giá trị mong muốn và không cung cấp sự bảo vệ đầy đủ khỏi việc quay lui, thì đó là một cơn ác mộng ngoài tầm kiểm soát

Đây là hình thức chung cho các thẻ cũ đơn giản. Lưu ý [\w:] đại diện cho tên thẻ?

 <     
 (?:
      [\w:]+ 
      \s+ 
      (?:
           " [\S\s]*? " 
        |  ' [\S\s]*? ' 
        |  [^>]? 
      )+
      \s* /?
 )
 >

Tiếp tục, chúng tôi cũng thấy rằng bạn không thể tìm kiếm một thẻ cụ thể mà không phân tích cú pháp TẤT CẢ các thẻ. Ý tôi là bạn có thể, nhưng nó sẽ phải sử dụng kết hợp các động từ như (*SKIP)(*FAIL) nhưng tất cả các thẻ vẫn phải được phân tích cú pháp

Lý do là cú pháp thẻ có thể bị ẩn bên trong các thẻ khác, v.v.

Vì vậy, để phân tích cú pháp tất cả các thẻ một cách thụ động, cần có biểu thức chính quy như bên dưới. Nội dung cụ thể này cũng phù hợp với nội dung vô hình

Trong số các lập trình viên có kinh nghiệm, việc cố gắng phân tích cú pháp HTML bằng các biểu thức chính quy thường được coi là một ý tưởng tồi. Làm thế nào xấu của một ý tưởng?

Bạn không thể phân tích cú pháp [X]HTML bằng regex. Bởi vì HTML không thể được phân tích cú pháp bằng regex. Regex không phải là một công cụ có thể được sử dụng để phân tích cú pháp HTML một cách chính xác. Như tôi đã trả lời trong các câu hỏi về HTML và regex ở đây rất nhiều lần trước đây, việc sử dụng regex sẽ không cho phép bạn sử dụng HTML

Biểu thức chính quy là một công cụ không đủ phức tạp để hiểu các cấu trúc được sử dụng bởi HTML. HTML không phải là ngôn ngữ thông thường và do đó không thể phân tích cú pháp bằng các biểu thức thông thường. Các truy vấn Regex không được trang bị để chia nhỏ HTML thành các phần có ý nghĩa của nó. rất nhiều lần nhưng nó không đến với tôi. Ngay cả các biểu thức chính quy không đều được nâng cao như được sử dụng bởi Perl cũng không phụ thuộc vào nhiệm vụ phân tích cú pháp HTML. Bạn sẽ không bao giờ làm cho tôi crack. HTML là một ngôn ngữ đủ phức tạp để không thể phân tích cú pháp bằng các biểu thức chính quy

Even Jon Skeet cannot parse HTML using regular expressions. Every time you attempt to parse HTML with regular expressions, the unholy child weeps the blood of virgins, and Russian hackers pwn your webapp. Parsing HTML with regex summons tainted souls into the realm of the living. HTML and regex go together like love, marriage, and ritual infanticide. The

cannot hold it is too late. The force of regex and HTML together in the same conceptual space will destroy your mind like so much watery putty. If you parse HTML with regex you are giving in to Them and their blasphemous ways which doom us all to inhuman toil for the One whose Name cannot be expressed in the Basic Multilingual Plane, he comes.

(Hành động unicode trong bài đăng, không được hiển thị ở đây, là phần hay nhất của trò đùa. )

Đúng vậy, nếu bạn cố gắng phân tích cú pháp HTML bằng các biểu thức thông thường, bạn sẽ không chống lại được sự cám dỗ của mã … er … của vị thần bóng tối Cthulhu

Làm cách nào để phân tích cú pháp trang HTML bằng biểu thức chính quy?

Điều này hoàn toàn thú vị, nhưng lời cảnh báo ở đây chỉ là một phần của lời nói suông, và nó sinh ra từ một sự thất vọng rất thực tế

Tôi đã nghe lập luận này trước đây. Thông thường, tôi nghe nó như là lời biện minh cho việc nhìn thấy một cái gì đó giống như đoạn mã sau.
# pull out data between 
tags ($table_data) = $html =~ /(.*?)