我有两个文件,XML和HTML,需要从某些模式中提取数据。
我的XML文件格式很好,我可以使用readline读取一行并在标签之间搜索数据。
if($line =~ /\<tag1\>$varvalue\<\/tag1\>/)`
然而,对于我的HTML,它有我见过的最糟糕的代码之一,文件是:
<div class="theater">
<h2>
<a href="/showtimes/university-village-3" >**University Village 3**</a></h2>
<div class="address">
<i>**3323 South Hoover Street, Los Angeles CA 90007 | (213) 748-6321**</i>
</div>
</div>
<div class="mtitle">
<a href="/movie/dream-house-2011" title="Dream House" onmouseover="mB(event, 771204354);" >**Dream House**</a>
<span>**(PG-13 , 1 hr. 31 min.)**</span>
</div>
<div class="times">
**1:00 PM,**
</div>
现在从这个文件我需要选择以粗体显示的数据。
我可以使用Perl正则表达式来搜索此文件中的数据。
答案 0 :(得分:6)
RegEx match open tags except XHTML self-contained tags
http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html
Using regular expressions to parse HTML: why not?
当你读完那些回来后:)
编辑:要实际解决您的问题,请看一下这个模块:
http://perlmeme.org/tutorials/html_parser.html
解析html文件的一些示例:
#!/usr/local/bin/perl
use HTML::TreeBuilder;
$tree = HTML::TreeBuilder->new;
$tree->parse_file('C:\Users\Stefanos\workspace\HTML_Parser_Test\test.html');
@divs = $tree->find('div');
$tree->delete;
在这个例子中,我只使用你的标签作为.html文件的主体。 div存储在@divs数组中。因为我不知道你想找哪个文本,因为**不是一个元素,我无法帮你进一步..
P.S。我从来没有使用过这个模块,但我只是在5分钟内完成了它,因此解析html文件并找到你想要的东西并不是那么难......
正则表达式匹配任何特定标记和内容存储结果为$ 1:
if ($subject =~ m!<tagname[^>]*>(.*?)</tagname>!s) {
# Successful match
}
虽然在嵌套元素时很快就会意识到这种方法的局限性。
将tagname替换为实际标记..例如在你的情况下我,a,span,div虽然对于div你也会得到第一个div的内容,这不是你想要的..
答案 1 :(得分:0)
Parsing XML and HTML using regular expressions is a fool's errand。有许多简单易用的Perl模块用于解析HTML。这是使用HTML::TokeParser::Simple的内容。我省略了将电影和放映时间与影院相关联的代码(因为我无意构建合适的输入文件):
#!/usr/bin/env perl
use strict; use warnings;
use HTML::TokeParser::Simple;
my $parser = HTML::TokeParser::Simple->new(handle => \*DATA);
my @theaters;
while (my $div = $parser->get_tag('div')) {
my $class = $div->get_attr('class');
next unless defined($class) and $class eq 'theater';
my %record;
$record{theater} = $parser->get_text('/a');
$record{address} = $parser->get_text('/i');
s{(?:^\s+)|(?:\s+\z)}{} for values %record;
push @theaters, \%record;
}
use YAML;
print Dump \@theaters;
__DATA__
<div class="theater">
<h2>
<a href="/showtimes/university-village-3" >**University Village 3**</a></h2>
<div class="address">
<i>**3323 South Hoover Street, Los Angeles CA 90007 | (213) 748-6321**</i>
</div>
</div>
<div class="mtitle">
<a href="/movie/dream-house-2011" title="Dream House" onmouseover="mB(event, 771204354);" >**Dream House**</a>
<span>**(PG-13 , 1 hr. 31 min.)**</span>
</div>
<div class="times">
**1:00 PM,**
</div>
<div class="theater">
<h2>
<a href="/showtimes/university-village-3" >**Some other theater*</a></h2>
<div class="address">
<i>**1234 South Hoover Street, St Paul, MN 99999 | (999) 748-6321**</i>
</div>
</div>
输出:
[sinan@macardy]:~/tmp> ./tt.pl --- - address: '**3323 South Hoover Street, Los Angeles CA 90007 | (213) 748-6321**' theater: '**University Village 3**' - address: '**1234 South Hoover Street, St Paul, MN 99999 | (999) 748-6321**' theater: '**Some other theater*'