0

我一直在做一些事情,它需要一个带有参考书目的 html 文件,并剥离除作者之外的所有内容。我很难摆脱一些无关的数据,例如 html 标签中的字符。我希望能够剥离整个标签,甚至更好的是标签之间的特定数据。

现在这是我的潜艇的样子:

    sub extractAuthorsIntoArray{
        @author_array = split /[<>"\/?!.=\(\)1234567890':]/, $doc;
        foreach(@author_array){
            print "$_" . "\n";
        }
    }

此时它所做的是剥离所有标签字符,但它留下了一堆我不想要的无关数据,例如发布日期以及出版物名称和我不需要的其他数据。每当我试图摆脱说“<li>”时,它都会给我我的新数据,而这些字符完全丢失了。不管怎样,我会继续努力的。

后来。

编辑:

我想做的是这样的:

<li value="2">Artem Chebotko 和 Shiyong Lu,<b>“用于高效评估 SPARQL 嵌套可选图模式的嵌套可选连接”</b>。< i>Progressive Concepts for Semantic Web Evolution: Applications and Developments</i>,Miltiadis Lytras 和 Amit Sheth (Eds.),信息科学出版社,ISBN 160566992X,2010。< br/>< br/></li> < li>Artem Chebotko、Shiyong Lu、Farshad Fotouhi 和 Anthony Aristar,<b>“基于本体的语义网多媒体语言数据注释”</b>。< i>基于 Web 的语义信息系统:最先进的应用程序</i>,Amit Sheth 和 Miltiadis Lytras(主编),IGI Global,ISBN 1599044269,2006。< br/>< br/>< /li>

最后得到这个:

Artem Chebotko 和 Shiyong Lu

4

4 回答 4

1

我的建议:不要使用正则表达式。取而代之的是,使用HTML::Parser或 CPAN 提供的众多模块之一。

于 2013-03-17T08:02:12.167 回答
1

如果对数据的结构没有一定的把握,这个问题通常很难解决,但根据你的例子,我会假设作者总是你数据的第一个非标签内容,并以逗号结尾(这是一种非常常见的格式)。

这意味着问题有两个部分:去掉任何初始 HTML 标记,然后删除逗号后的所有内容。

首先,HTML 标记相当容易识别,因为它以这些字符开头<和结尾,>并且不能包含其中任何一个字符。所以:

$line =~ s{ \A \s* (?: < [^>]+ > \s* )+ }{}xms;

将删除行首的所有 HTML 标记(和空格)。(这使用了Perl Best Practices/x推荐的标志和其他编码样式。)逐步完成此操作,匹配字符串的开头,匹配任意数量的空格,核心是,通过查找匹配 HTML 标记标签的开头,然后取一个或多个字符,直到标签的结尾。这包含在允许任意数量的它们中。(我使用而不是仅仅因为如果您不关心保持匹配,最好关闭捕获。)\A\s*< [^>]+ >(?: )+(?:)()

之后从逗号中删除所有内容要容易得多:

$line =~ s{ , .* }{}xms;

现在,这假设每个 bibiography 条目都是程序中的单个标量。这掩盖了一个相当大的问题。相反,如果您有一个包含整个页面的变量,则可能需要对其进行解析。如果每个条目都是一个<li>标签,你要做的是提取每个<li>标签的内容,然后像上面一样处理它。

为此,请在列表上下文中使用执行以下操作的/g选项进行匹配:

my @entries = ($doc =~ m{ <li (?: \s [^>] )? > (.*?) </li> }xmsg);

这里还有一些微妙之处。后面的(?: )?<li可选地匹配空格后跟一些字符,而不是>允许该标记的任何属性。该(.*?)部分执行提取标签内容的实际工作。注意. ?_ *这使得匹配是非贪婪的,这意味着它不是将所有内容匹配到文档中的最后一个 </li>标签,而是将所有内容匹配到第一个 </li>标签。最后,/g修饰符表示尽可能多地重复此匹配,并将捕获的内容()作为列表返回。

于 2013-03-17T08:53:20.480 回答
1

这是一种相当……不寻常的……使用方式split。当您的数据包含由分隔符分隔的多个数据项时,通常使用它来拆分这些分隔符上的数据并检索各个项目。这不是您要在这里执行的操作,因此split可能不是您要查找的droid命令。

如前所述,正确的 HTML 解析器确实是做到这一点的正确方法,但您特别想将正则表达式用于教育目的,所以我会给您一个。请注意,使用正则表达式解析 HTML 充满危险,而且几乎可以肯定在某些极端情况下会失败。

所以,那说:

#!/usr/bin/env perl    

use strict;
use warnings;
use 5.010;

my $text = q[< li value="2">Artem Chebotko and Shiyong Lu, < b>"Nested Optional Join for Efficient Evaluation of SPARQL Nested Optional Graph Patterns"< /b>. < i>Progressive Concepts for Semantic Web Evolution: Applications and Developments< /i>, Miltiadis Lytras and Amit Sheth (Eds.), Information Science Publishing, ISBN 160566992X, 2010.< br/>< br/>< /li> < li>Artem Chebotko, Shiyong Lu, Farshad Fotouhi, and Anthony Aristar, < b>"Ontology-Based Annotation of Multimedia Language Data for the Semantic Web"< /b>. < i>Semantic Web-Based Information Systems: State-of-the-Art Applications< /i>, Amit Sheth and Miltiadis Lytras (Eds.), IGI Global, ISBN 1599044269, 2006.< br/>< br/>< /li>];

my @list_items = $text =~ m[<\s*li(?:\s+[^>]*)?>(.*?)<\s*/li\s*>]g;

my @authors;
for (@list_items) {
  /([^<]+), </;
  push @authors, $1;
}

say for @authors;

输出:

Artem Chebotko and Shiyong Lu
Artem Chebotko, Shiyong Lu, Farshad Fotouhi, and Anthony Aristar
于 2013-03-17T09:06:20.163 回答
0
#!/usr/bin/perl -w

use strict;
read DATA, my $string, -s DATA;
my @matches = ( $string =~ /<\s+li\s*(?:.*?)>(.+?),\s+<\s+b>/g );
print "$_\n\n" foreach (@matches);

__DATA__
< li value="2">Artem Chebotko and Shiyong Lu, < b>"Nested Optional Join for Efficient Evaluation of SPARQL Nested Optional Graph Patterns"< /b>. < i>Progressive Concepts for Semantic Web Evolution: Applications and Developments< /i>, Miltiadis Lytras and Amit Sheth (Eds.), Information Science Publishing, ISBN 160566992X, 2010.< br/>< br/>< /li> < li>Artem Chebotko, Shiyong Lu, Farshad Fotouhi, and Anthony Aristar, < b>"Ontology-Based Annotation of Multimedia Language Data for the Semantic Web"< /b>. < i>Semantic Web-Based Information Systems: State-of-the-Art Applications< /i>, Amit Sheth and Miltiadis Lytras (Eds.), IGI Global, ISBN 1599044269, 2006.< br/>< br/>< /li>

如果您愿意解决这个特定问题,那么您的正则表达式应该寻找的是:

a) < li value="2">AUTHORS, < b>
b) < li>AUTHORS, < b>

对于 a) 一种可能的正则表达式是:

< \s+ li \s+ value="2"> (.+), \s+ <\s+b>

对于 b) 一种可能的正则表达式是:

< \s+ li> (.+), \s+ <\s+b>

结合这两个正则表达式产生:

<\s+li\s*(?:.*?)>(.+?),\s+<\s+b>

不优雅等,但也许它会帮助你。

于 2013-03-17T09:16:30.340 回答