2009-07-01 5 views
8

Есть ли в любом случае проще, чем это сделать, чтобы удалить HTML из строки с помощью Perl?Как я могу поместить HTML в строку с помощью 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; 

Я бы оценил как сглаженное регулярное выражение, например. что-то вроде этого:

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

Есть ли существующая функция Perl, которая удаляет любые/все HTML из строки, даже если мне нужна только жирный шрифт, h1 заголовков и уша раздел?

ответ

18

Предполагая, что код является действительным HTML (не бездомная < или> операторы)

Если вам необходимо удалить только жирным шрифтом, h1-х и БР

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

И вы могли бы хотеть рассмотреть HTML::Strip модуль

+5

Я бы не сказал, мог бы, я бы сказал, должен. Пытаться дезинформировать HTML с помощью регулярных выражений абсурдно в этот день и в возрасте. Используйте один из многочисленных HTML-санирующих модулей из CPAN, желательно что-то предназначенное для предотвращения уязвимостей XSS и не написанное Дэниелом Мьюи. – 2009-07-02 10:52:04

+2

Остерегайтесь HTML :: Strip неправильно поддерживает кодированные строки UTF-8.См. Здесь обход https://gist.github.com/910818 – nick

14

От perlfaq9: How do I remove HTML from a string?


Самый правильный способ (хотя и не самый быстрый) - использовать HTML :: Parser из CPAN. Другим наиболее правильным способом является использование HTML :: FormatText, который не только удаляет HTML, но и пытается сделать небольшое простое форматирование полученного текстового текста.

Многие люди пытаются использовать простой подход к регулярному выражению, например s/<. *?> // g, но это во многих случаях терпит неудачу, поскольку теги могут продолжаться по разрыву строк, они могут содержать закодированные угловые скобки, или комментарий HTML может присутствовать. Кроме того, люди забывают конвертировать объекты - например, <.

Вот один «простодушный» подход, который работает для большинства файлов:

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

Если вы хотите получить более полное решение, увидеть программу striphtml 3 этапа в http://www.cpan.org/authors/id/T/TO/TOMC/scripts/striphtml.gz.

Вот некоторые сложные случаи, которые вы должны думать о том, выбирая решение:

<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 [ >>>>>>>>>>>> ]]> 

Если комментарии HTML включают в себя другие теги, эти решения также сломаться по тексту, как это:

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

К вашему предложению к сценарию - http://www.cpan.org/authors/id/T/TO/TOMC/scripts/striphtml.gz - это удаляет все. Как я могу изменить этот код, чтобы оставить определенные теги html? Кроме того, он работает хорошо. – PKHunter

14

Вы обязательно должны взглянуть на HTML::Restrict, который позволяет вам отменить или ограничить допустимые HTML-теги. Минимальный пример, который отсекает все HTML-теги:

use HTML::Restrict; 

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

Я бы рекомендовал держаться подальше от HTML :: Газа из-за it breaks utf8 encoding.

+0

Хотел бы я прочитать этот ответ несколько недель назад. – Steven

+0

Он не работает с Perl 5.8.x. Это супер-программа, но было бы неплохо узнать, какова ее структура поддержки. – PKHunter

+0

Также я не уверен, есть ли способ оставить теги (допустимые теги), у которых нет открытых и закрытых тегов. Пример '
' трудно идентифицировать. – PKHunter

Смежные вопросы