2009-07-01 37 views
8

Có cách nào dễ dàng hơn điều này để tách HTML khỏi chuỗi bằng Perl không?Làm cách nào để tách HTML trong chuỗi bằng Perl?

$Error_Msg =~ s|<b>||ig; 
$Error_Msg =~ s|</b>||ig; 
$Error_Msg =~ s|<h1>||ig; 
$Error_Msg =~ s|</h1>||ig; 
$Error_Msg =~ s|<br>||ig; 

Tôi sẽ biểu thị cả biểu thức chính quy được rút gọn, ví dụ: một cái gì đó như thế này:

$Error_Msg =~ s|</?[b|h1|br]>||ig; 

Có một hàm Perl hiện có loại bỏ bất kỳ/tất cả HTML từ chuỗi, mặc dù tôi chỉ cần in đậm, tiêu đề h1 và br tước?

Trả lời

18

Giả sử mã là HTML hợp lệ (không đi lạc < hoặc> khai thác)

Nếu bạn cần phải loại bỏ chỉ bolds, của h1 và br của

$htmlCode =~ s#</?(?:b|h1|br)\b.*?>##g 

Và bạn có thể muốn xem xét việc HTML::Strip mô-đun

+5

Tôi sẽ không nói có thể, tôi sẽ nói nên. Cố gắng để khử trùng HTML với các regex là vô lý trong ngày và tuổi tác. Sử dụng một trong nhiều mô-đun vệ sinh HTML từ CPAN, tốt hơn là một cái gì đó được thiết kế để ngăn chặn lỗ hổng XSS và không được viết bởi Daniel Muey. –

+2

Hãy coi chừng HTML :: Dải không hỗ trợ đúng các chuỗi được mã hóa UTF-8.Xem tại đây để biết cách giải quyết https://gist.github.com/910818 – nick

14

Từ perlfaq9: How do I remove HTML from a string?


Cách chính xác nhất (mặc dù không phải là nhanh nhất) là sử dụng HTML :: Trình phân tích cú pháp từ CPAN. Một cách chủ yếu khác là sử dụng HTML :: FormatText không chỉ loại bỏ HTML mà còn cố gắng tạo một định dạng đơn giản của văn bản thuần túy.

Nhiều người cố gắng tiếp cận biểu thức chính quy đơn giản, như s/<. *?> // g, nhưng không thành công trong nhiều trường hợp vì các thẻ có thể tiếp tục bị ngắt dòng, chúng có thể chứa dấu ngoặc nhọn được trích dẫn, hoặc nhận xét HTML có thể có mặt. Ngoài ra, mọi người đều quên chuyển đổi các thực thể - chẳng hạn như < chẳng hạn.

Dưới đây là một "đầu óc đơn giản" cách tiếp cận, mà làm việc cho hầu hết các tập tin:

#!/usr/bin/perl -p0777 
s/<(?:[^>'"]*|(['"]).*?\1)*>//gs 

Nếu bạn muốn có một giải pháp hoàn chỉnh hơn, hãy xem các chương trình striphtml 3 giai đoạn trong http://www.cpan.org/authors/id/T/TO/TOMC/scripts/striphtml.gz.

Dưới đây là một số trường hợp khó khăn mà bạn nên suy nghĩ về khi chọn một giải pháp:

<IMG SRC = "foo.gif" ALT = "A > B"> 

<IMG SRC = "foo.gif" 
ALT = "A > B"> 

<!-- <A comment> --> 

<script>if (a<b && a>c)</script> 

<# Just data #> 

<![INCLUDE CDATA [ >>>>>>>>>>>> ]]> 

Nếu HTML bình luận bao gồm các thẻ khác, những giải pháp cũng sẽ phá vỡ trên văn bản như thế này:

<!-- This section commented out. 
    <B>You can't see me!</B> 
--> 
+0

Đề xuất tập lệnh của bạn - http://www.cpan.org/authors/id/T/TO/TOMC/scripts/striphtml.gz - điều này xóa mọi thứ. Làm thế nào tôi có thể sửa đổi mã này để chỉ để lại một số thẻ html? Khác hơn là nó hoạt động tốt. – PKHunter

14

Bạn chắc chắn nên có một cái nhìn tại HTML::Restrict cho phép bạn loại bỏ hoặc hạn chế các thẻ HTML được cho phép. Một ví dụ tối thiểu để loại bỏ tất cả các thẻ HTML:

use HTML::Restrict; 

my $hr = HTML::Restrict->new(); 
my $processed = $hr->process('<b>i am bold</b>'); # returns 'i am bold' 

Tôi khuyên bạn nên tránh xa HTML :: Strip vì it breaks utf8 encoding.

+0

Tôi muốn đọc câu trả lời này cách đây vài tuần. – Steven

+0

Nó không hoạt động với Perl 5.8.x. Đó là một chương trình siêu, nhưng nó sẽ là tốt đẹp để biết cấu trúc hỗ trợ của nó là gì. – PKHunter

+0

Ngoài ra tôi không chắc chắn nếu có một cách để lại các thẻ (thẻ cho phép) mà không có thẻ mở và đóng. Ví dụ '
' khó xác định. – PKHunter

Các vấn đề liên quan