2008-09-22 25 views
6

Giả sử tôi có một chuỗi giữ một chuỗi văn bản và (x) các thẻ HTML. Tôi muốn xóa tất cả các phiên bản của một thẻ nhất định (và bất kỳ thuộc tính nào của thẻ đó), để lại tất cả các thẻ và văn bản khác. Regex tốt nhất để làm điều này là gì?Tôi đang tìm một biểu thức chính quy để xóa một thẻ HTML (x) đã cho ra khỏi một chuỗi

Đã chỉnh sửa để thêm: Ồ, tôi đánh giá cao việc sử dụng Regex cho vấn đề cụ thể này không phải là giải pháp tốt nhất. Tuy nhiên, vì mục đích thảo luận, chúng tôi có thể giả định rằng quyết định kỹ thuật cụ thể đó đã được thực hiện một vài cấp độ so với mức lương của tôi? ;)

Trả lời

17

Cố gắng phân tích cú pháp HTML bằng các cụm từ thông dụng thường là ý tưởng tồi cực kỳ. Thay vào đó, hãy sử dụng trình phân tích cú pháp, phải có một trình phân tích cú pháp cho ngôn ngữ bạn đã chọn.

Bạn thể có thể nhận được ngay với một cái gì đó như thế này:

</?tag[^>]*?> 

Nhưng nó phụ thuộc vào chính xác những gì bạn đang làm. Ví dụ: điều đó sẽ không xóa nội dung của thẻ và có thể khiến HTML của bạn ở trạng thái không hợp lệ, tùy thuộc vào thẻ bạn đang cố xóa. Nó cũng đối phó xấu với HTML không hợp lệ (và có rất nhiều điều đó về).

Sử dụng một cú pháp thay :)

+0

Đổ lỗi, đừng chạy niềm vui cho tất cả những người tạo các regex với câu trả lời rõ ràng của bạn! – Will

+0

Bạn cần phải làm điều đó * không tham lam (*?) Hoặc bạn sẽ mất mọi thứ từ thẻ được so khớp đầu tiên với ký tự lớn hơn cuối cùng trong chuỗi của bạn. – Prestaul

0

Tôi nghĩ rằng nó có thể là Raymond Chen (blogs.msdn.com/oldnewthing) mà tôi đang diễn giải (nặng!) Ở đây ... Tuy nhiên, bạn muốn có một Regular Expression ? "Bây giờ bạn có hai vấn đề" ...: =)

Nếu chuỗi là hình thức tốt (X) HTML, bạn có thể tải nó lên trong một trình phân tích cú pháp (HTML/XML) và sử dụng nó để loại bỏ bất kỳ nút nào của loại vi phạm? Nếu nó không được hình thành tốt, thì nó trở nên phức tạp hơn một chút, nhưng, tôi nghi ngờ rằng RegEx không phải là cách tốt nhất để thực hiện việc này ...

+0

Raymond Chen đã sử dụng tuyên bố đó, nhưng ông đã trích dẫn Jaime Zawinski. –

0

Chỉ có rất nhiều cách để một thẻ có thể xuất hiện , chưa kể đến mã hóa, biến thể, v.v.
Tôi khuyên bạn nên suy nghĩ lại cách tiếp cận này .... bạn thực sự không cần phải xử lý HTML trực tiếp.

0

Tắt đầu của tôi, tôi muốn nói điều này sẽ giúp bạn bắt đầu đi đúng hướng.

s/<TAG[^>]*>([^<]*)</TAG[^>]*>/\1 

Về cơ bản, tìm thẻ bắt đầu, bất kỳ văn bản nào giữa các thẻ và sau đó là thẻ kết thúc. Thay thế toàn bộ thứ bằng bất kỳ thứ gì nằm giữa các thẻ.

15

Tôi nghĩ rằng có một số vấn đề nghiêm trọng chống regex xảy ra ở đây. Có rất nhiều lần bạn có thể muốn tách một thẻ cụ thể ra khỏi một số đánh dấu khi nó không có ý nghĩa để sử dụng một trình phân tích cú pháp đầy đủ.

Tất nhiên có những lúc một phân tích cú pháp có thể là lựa chọn tốt nhất, nhưng nếu bạn đang tìm kiếm một regex thì:

<script[^>]*?>[\s\S]*?<\/script> 

Điều đó sẽ loại bỏ các thẻ kịch bản và nội dung của họ. Đảm bảo rằng bạn sử dụng kết hợp phân biệt chữ hoa chữ thường.

Nếu bạn không muốn loại bỏ các nội dung của thẻ thì bạn có thể sử dụng:

<\/?script[^>]*?> 

Một ví dụ về việc sử dụng trong javascript sẽ là:

function stripScripts(markup) { 
    return markup.replace(/<script[^>]*?>[\s\S]*?<\/script>/gi, ''); 
} 

var safeText = stripScripts(textarea.value); 
+1

Hey không có gì sai với biểu thức thông thường, nó chỉ là bạn không thể viết một phân tích cú pháp HTML trong một (thực sự, tôi nghĩ rằng bạn có thể trong Perl (perl có một số công cụ regex thêm), nhưng bagy không duy trì nó!). – Dan

+0

Tôi đồng ý với bạn. Đôi khi bạn chỉ muốn hành động trên một trang nhất định, với cấu trúc nổi tiếng, hoặc HTML được tạo ra bởi một công cụ, với đầu ra được xác định rõ. Khi mã có thể dự đoán được, sử dụng regex có thể có ý nghĩa. Sử dụng chúng để phân tích cú pháp bất kỳ HTML nào do con người nhập là nguy hiểm hơn! ;-) – PhiLho

0

câu trả lời Corrected:

</?TAG\b[^>]*?> 

Vì câu trả lời của Dans sẽ xóa <br />, nhưng bạn chỉ muốn <b>

0

Dưới đây là một regex tôi đã viết cho mục đích này, nó hoạt động trong một vài tình huống hơn:

</?(?(?=b|img|a|script)notag|[a-zA-Z0-9]+)(?:\s[a-zA-Z0-9\-]+=?(?:(["",']?).*?\1?)?)*\s*/?> 
0

Trong khi sử dụng regexes cho phân tích cú pháp HTML thường được tán thành hay nhìn xuống, bạn gần như chắc chắn không muốn để viết trình phân tích cú pháp của riêng bạn.

Tuy nhiên, bạn có thể sử dụng một số chức năng sẵn có hoặc thư viện để đạt được những gì bạn cần.

  • JavaScript có getElementsByTagNamegetElementById, chưa kể jQuery.
  • PHP có tiện ích mở rộng DOM.
  • Python có tuyệt vời Beautiful Soup
  • ... và nhiều hơn nữa.
Các vấn đề liên quan