使用多行regex perl查找多个匹配项

时间:2012-11-14 03:36:07

标签: perl

此代码:

#!/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仅返回第一个匹配项。我读过尽可能多的帖子,但是没有成功吗?

我做错了什么?

1 个答案:

答案 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') };
}