简单的Perl正则表达式解析器

时间:2010-09-13 04:34:52

标签: regex perl parsing

嘿,我正在研究一个非常基本的解析器。我几乎可以肯定我的正则表达式是正确的,但值似乎没有存储在我的$1$2中。难道我做错了什么?我只是在寻找改变代码的技巧。谢谢你的建议!另外,我是Perl的新手,所以如果我做错了什么,我希望能够站稳脚跟并养成良好的习惯。

文件中的示例行:

Sat 02-August-2008 20:47 - 123.112.3.209 - "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;

我只是从时代开始。

foreach my $line (@lines)
{   
my $match =~ /\d\d-\w+-\d{4} (\d)(\d):\d\d/;

if( $1 == 0)
{
    $times[$2] = $times[$2] + 1;
}
else
{   
    my $time = $1.$2;
    $times[$time] = $times[$time]+ 1;
}
 }


print "\n";
for(my $i=0;$i<24;$i++)
{
print "$i: $times[$i]\n";
}

3 个答案:

答案 0 :(得分:7)

如果您想在$line上匹配,则不应将代码读取

$line =~ /\d\d-\w+-\d{4} (\d)(\d):\d\d/;

See here

答案 1 :(得分:3)

您能举例说明您尝试匹配的模式吗?否则我将无法判断你的正则表达式是否与你的模式匹配。但是,您可以对代码进行一些改进:

首先,如果您想使用$ 1,$ 2等

,请始终测试匹配是否成功
if($match =~ /\d\d-\w+-\d{4} (\d)(\d):\d\d/) {

    if( $1 == 0)
    {
        $times[$2] = $times[$2] + 1;
    }
    else
    {   
        my $time = $1.$2;
        $times[$time] = $times[$time]+ 1;
    }
} else {
    warn "no match!\n";
}

其次,始终使用'-w'开关。在这种情况下,由于匹配失败,您可能会收到大约$ 1和$ 2的警告消息:

#!/usr/bin/perl -w

答案 2 :(得分:1)

首先,如果您是Perl的新手,其中一个优势是CPAN和那里的众多解决方案。不要重新发明轮子!

有一个名为Date::Parse的强大模块可以为您解析时间部分。那么你唯一的正则表达式问题是分离出你的行的时间部分。

根据您的一行示例,此代码将执行此操作:

use strict;
use warnings;

use Date::Parse;

my $line="Sat 02-August-2008 20:47 - 123.112.3.209 - \"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;";
my $tmpart;

if ($line=~ /^(.*\d+:\d+) -/) {
    $tmpart=$1;

    print "Time part = $tmpart\n";

    my $time=str2time($tmpart);
    my ($ss,$mm,$hh,$day,$month,$year,$zone) = strptime($tmpart);

    $year+=1900;
    $month+=1;

    print "Unix time: $time\n";
    print "Parsed time: $month/$day/$year $hh:$mm:$ss  \n\n";
} 
else {
   warn "no match!\n";
}   

这将返回一个易于使用的Unix时间号。或者(如图所示)您可以解析时间的各个组成部分。