我将使用什么来从大型数据集中删除转义的html

时间:2010-04-13 17:09:58

标签: mysql perl

我们的数据库中填充了从RSS源检索到的文章。我不确定我将获得什么数据,以及已经设置了多少过滤(使用SimplePie库的WP-O-Matic Wordpress插件)。这个插件在插入之前使用Wordpress的内置后插入功能进行一些基本编码,后者也进行了一些过滤。在RSS feed的编码,使用PHP的插件编码,Wordpress的编码和SQL转义之间,我不知道从哪里开始。

在我想要保留的内容之后,数据通常位于字段的末尾。它全部在一条线上,但为了便于阅读而分开:

<img src="http://feeds.feedburner.com/~ff/SoundOnTheSound?i=xFxEpT2Add0:xFbIkwGc-fk:V_sGLiPBpWU" border="0"></img>

<img src="http://feeds.feedburner.com/~ff/SoundOnTheSound?d=qj6IDK7rITs" border="0"></img>

&lt;img src=&quot;http://feeds.feedburner.com/~ff/SoundOnTheSound?i=xFxEpT2Add0:xFbIkwGc-fk:D7DqB2pKExk&quot;

注意一些图像是如何逃脱的,而另一些则不是。我认为这与被切断的最后一部分有关,因此无法识别为html标记,然后导致它被html结束,而实际的img标记被单独留下。

另一条记录在其中一个字段中这个,这意味着RSS提要没有为该项目提供任何内容(现已过滤掉,但我有一堆这样的记录):

&lt;img src=&quot;http://farm3.static.flickr.com/2183/2289902369_1d95bcdb85.jpg&quot; alt=&quot;post_img&quot; width=&quot;80&quot;

所有提取的样本都在一行,但为了便于阅读而分解。否则,它们将从命令行mysql客户端从数据库中完全复制。

问题:使用上述转义的html(或html标记的一部分)的最佳方法是什么,这样我就可以删除它而不影响内容?

我想删除它,因为字段末尾的图像通常是与内容无关的图像。对于进料燃烧器,进料燃烧器将其添加到进料中的每个物品中。其他时候,它们是破碎图像周围的链接。这一点不是可以轻松删除的有效html img标签。它是被破坏的标签,如果未编码将不是有效的html,这将无法使用您的标准html解析器进行解析。

[编辑] 的 如果只是拉动我想要的html并执行strip_tags并重新插入数据,我就不会问这个问题。

我遇到问题的部分是曾经是img标签的部分是html编码并且结束了。如果它被解码,它将成为一个html标签,所以我不能以通常的方式解析它。

对于所有&lt;img src=&quot;垃圾,除了SELECT ID, post_content FROM table WHERE post_content LIKE '&lt;img'之外,我无法解决它,至少让我知道那些帖子。但是当我获得数据时,我需要一种方法来找到它,删除它,但保留其余的内容。

[/编辑]

[编辑2]

<img src="http://farm4.static.flickr.com/3162/2735565872_b8a4e4bd17.jpg" alt="post_img" width="80" />Through the first two months of the year, the volume of cargo handled at Port of Portland terminals has increased 46 percent as the port?s marine cargo business shows signs of recovering from a dismal 2009.<div> <a href="http://feeds.bizjournals.com/~ff/bizj_portland?a=YIs66yw13JE:_zirAnH6dt8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/bizj_portland?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.bizjournals.com/~ff/bizj_portland?a=YIs66yw13JE:_zirAnH6dt8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/bizj_portland?i=YIs66yw13JE:_zirAnH6dt8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.bizjournals.com/~ff/bizj_portland?a=YIs66yw13JE:_zirAnH6dt8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/bizj_portland?i=YIs66yw13JE:_zirAnH6dt8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.bizjournals.com/~ff/bizj_portland?a=YIs66yw13JE:_zirAnH6dt8:qj6IDK7rITs">&lt;img src=&quot;http://feeds.feedburner.com/~ff/bizj_portland?d=qj6IDK7rITs&quot;

我要保留的部分:

<img src="http://farm4.static.flickr.com/3162/2735565872_b8a4e4bd17.jpg" alt="post_img" width="80" />Through the first two months of the year, the volume of cargo handled at Port of Portland terminals has increased 46 percent as the port?s marine cargo business shows signs of recovering from a dismal 2009.

重申:这不是关于删除有效的html img标签。这很简单。我需要能够找到具体的&lt;img src=&quot;http://feeds.feedburner.com/~ff/bizj_portland?d=qj6IDK7rITs&quot;,如果它是img标签img标签的模式img标签或锚定img锚定img img img mangled图像等的模式的一部分,但 remove { {1}}如果它确实是文章的一部分。在我评论的几十个样本中,这个错误的img标签位于该领域的最后是非常一致的。

另一个是单个损坏的图像标签。它一直是一个受损的flickr img标签,但如上所述,我不能只搜索&lt;img,因为它可能是内容的有效部分。

问题在于我不能简单地解码它并将其解析为HTML,因为它不是有效的HTML。 [/ EDIT 2]

6 个答案:

答案 0 :(得分:3)

最好的方法是:

  1. 从CPAN安装HTML::Entities并使用它来取消URI。
  2. 从CPAN安装HTML::Parser并使用它来解析并删除未转义后的URI。
  3. 正则表达式不适合执行此任务。

答案 1 :(得分:2)

我不会把它剥掉。它远非不可恢复的垃圾。

首先有条件地应用HTML::Entities::decode_entities(使用<的出现作为第一个字符作为启发式),然后让HTML::Tidy::libXML->clean(…, 'UTF-8', 1)按预期重建标记。 clean会返回一个完整的文档,但只提取所需的img元素是微不足道的。

答案 2 :(得分:2)

问题已更新......

要提取所需的数据,您可以使用以下方法:

use HTML::Entities qw/decode_entities/;

my $decoded = decode_entities $raw;

if ($decoded =~ s{ (<img .+? (?:>.+?</img>|/>)) } {}x) {  # grab the image
    my $img = $1;
    $decoded =~ s{<.+?>}      {}xg;  # strip complete tags
    $decoded =~ s{< [^>]+? $} {}x;   # strip trailing noise

    print $img.$decoded;
}

使用正则表达式来解析HTML通常是不受欢迎的,但是,在这种情况下,它更多的是剥离与模式匹配的段。在对更大的数据集测试正则表达式后,您应该知道可能需要调整的内容。

希望这有帮助。

答案 3 :(得分:0)

一个愚蠢的简单Perl如何在包含您的数据的var上找到并替换...

foreach $line(@lines) {
    $line =~ s/&lt;/</gi;
    $line =~ s/&gt;/>/gi;
}

答案 4 :(得分:0)

您最好的选择是重新收集数据库中的所有文章,以免它们被截断和损坏。如果这不是一个选项那么......

根据您上面的示例,您似乎正在删除每篇文章的文本内容之后的所有内容。在您的示例中,文本内容后跟一个DIV标记和一组IMG标记,这些标记可能已经或可能没有被截断并被转换为HTML实体。

如果您的所有记录都相似,那么您可以删除最终的div标签及其后面的所有内容,并删除文本内容之后的所有内容,如下所示:

my $article = magic_to_get_an_article();
$article =~ s/<div>.*//s;
magic_to_store_article($article);

如果您的记录包含比此更复杂的内容,您最好使用HTML解析模块并仔细阅读文档,以了解它如何处理无效的HTML。

答案 5 :(得分:0)

鉴于您在帖子结尾处提供的样本输入和输出,以下内容将为您提供所需的输出:

#!/usr/bin/perl

use strict; use warnings;

use HTML::TokeParser::Simple;
my $parser = HTML::TokeParser::Simple->new( \*DATA );

if ( my $tag = $parser->get_tag('img') ) {
    print $tag->as_is;
    print $parser->get_text('div');
}

__DATA__
<img src="http://farm4.static.flickr.com/3162/2735565872_b8a4e4bd17.jpg" alt="post_img" width="80" />Through the first two months of the year, the volume of cargo handled at Port of Portland terminals has increased 46 percent as the port?s marine cargo business shows signs of recovering from a dismal 2009.<div> <a href="http://feeds.bizjournals.com/~ff/bizj_portland?a=YIs66yw13JE:_zirAnH6dt8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/bizj_portland?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.bizjournals.com/~ff/bizj_portland?a=YIs66yw13JE:_zirAnH6dt8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/bizj_portland?i=YIs66yw13JE:_zirAnH6dt8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.bizjournals.com/~ff/bizj_portland?a=YIs66yw13JE:_zirAnH6dt8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/bizj_portland?i=YIs66yw13JE:_zirAnH6dt8:F7zBnMyn0Lo" border="0"></img></a> <a href="http://feeds.bizjournals.com/~ff/bizj_portland?a=YIs66yw13JE:_zirAnH6dt8:qj6IDK7rITs">&lt;img src=&quot;http://feeds.feedburner.com/~ff/bizj_portland?d=qj6IDK7rITs&quot;

输出:

<img src="http://farm4.static.flickr.com/3162/2735565872_b8a4e4bd17.jpg" alt="po st_img" width="80" />Through the first two months of the year, the volume of car go handled at Port of Portland terminals has increased 46 percent as the port?s marine cargo business shows signs of recovering from a dismal 2009.

但是,我对你应该处理的每个块的大小和范围感到困惑。