此代码:
#!/bin/perl
BEGIN { $/ = undef; };
open (FILE,"file.txt") || die "Cannot open $FILE:$!";
while (<FILE>) {
my @matches;
if ( m#SelectEditPolicy\.do\?policyID=[0-9]{1,4}.*?">(.*?)</a>#sg) {
push (@matches,$1);
}
foreach $rec (@matches) {
print "$rec\n";
}
}
针对此文件:
>cat file.txt
SelectEditPolicy.do?policyID=2958')">
Test123 OLD</a>
SelectEditPolicy.do?policyID=6643')">
Test123 </a>
执行file.pl仅返回第一个匹配项。我读过尽可能多的帖子,但是没有成功吗?
我做错了什么?
答案 0 :(得分:1)
你做错了很多事。第一个突出显示的是BEGIN { $/ = undef; };
如果要覆盖文件,请在最小的适用范围内设置$/ = undef
。此外,一旦您决定啜饮文件,就没有理由使用while
循环来假装逐行读取它。
其次,您似乎已对HTML文件进行了一些预处理,以将其缩减为可以应用正则表达式的形式。使用像HTML::TokeParser::Simple这样的东西,你的生活会更容易。
#!/usr/bin/env perl
use strict;
use warnings;
my $content = do { local $/; <DATA> };
my @matches = ($content =~ m{
SelectEditPolicy\.do\?
policyID=[0-9]{1,4}[^>]*?">
([^<]*?)
</a>
}xsg );
print "$_\n" for @matches;
__DATA__
SelectEditPolicy.do?policyID=2958')">
Test123 OLD</a>
SelectEditPolicy.do?policyID=6643')">
Test123 </a>
输出:
Test123 OLD Test123
将HTML::TokeParser::Simple与原始HTML一起使用,我可能会做这样的事情(未经测试):
#!/usr/bin/env perl
use strict;
use warnings;
use HTML::TokeParser::Simple;
my $parser = HTML::TokeParser::Simple->new(url => 'http://example.com/');
my @policies;
while (my $tag = $parser->get_tag('a')) {
my $href = $tag->get_attr('href');
next unless defined $href;
next unless $href =~ /SelectEditPolicy\.do\?policyID=([0-9]{1,4})/;
push @policies, { $1 => $parser->get_text('/a') };
}