Простой Perl Regex парсер - PullRequest
       1

Простой Perl Regex парсер

3 голосов
/ 13 сентября 2010

Эй, я работаю над очень простым парсером.Я почти уверен, что мое регулярное выражение верно, но значения, похоже, не сохраняются в моих $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 ]

7 голосов
/ 13 сентября 2010

Если вы хотите найти совпадение на $line, не читайте код

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

Смотрите здесь .

3 голосов
/ 13 сентября 2010

Можете ли вы привести пример того, какому образцу вы пытаетесь соответствовать?В противном случае я не смогу сказать, соответствует ли ваше регулярное выражение вашему шаблону или нет.Однако есть некоторые улучшения, которые вы можете внести в свой код:

Во-первых, всегда проверяйте, если совпадение успешно, если вы хотите использовать $ 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
1 голос
/ 13 сентября 2010

Во-первых, если вы новичок в 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, с которым потом легко работатьИли (как показано) вы можете анализировать отдельные компоненты времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...