2012-05-15 3 views
1

У меня есть простой вопрос о проблеме с регулярным выражением.Задача регулярного выражения в Perl

Учитывая следующий пример строки:

Apr 2 13:42:32 sandbox izxp[12000]: Received disconnect from 10.11.106.14: 10: disconnected by user 

Мне нужно отделить эту строку в 4-х различных строк. Как вы можете видеть: дата (Apr 2), время (13:42:32), имя сервера (sandbox) и другие данные (izxp[12000]: Received disconnect from 10.11.106.14: 10: disconnected by user).

Это значения переменных после.

Я был бы очень рад, что кто-то может мне помочь!

Thx!

+1

Что вы пробовали? SO - это не место для выполнения заданий для вас. Попробуйте что-нибудь и задайте конкретные вопросы, когда вы не можете заставить его работать. –

+0

Да, вы правы, но теперь я не успеваю учиться и по регулярному выражению. Позже я также изучу эту главу. – Freddiboy

ответ

6

Для этой задачи немного проще использовать split.

my ($date1, $date2, $time, $host, $data) = split(' ', $str, 5); 
my $date = "$date1 $date2"; 
+0

И быстрее. Сплит вычисляется дешевле, чем при использовании регулярного выражения. Единственное предостережение в том, что он не проверяет соответствие строки шаблону или нет. –

+0

Благодарим вас за ответ! – Freddiboy

1

Я всегда использую то, что я называю «шаблонами сканирования» для этого типа вещей. Формат даты довольно легко:

/((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d+) 

выражение для времени не намного сложнее

/(\d\d:\d\d:\d\d)/ 

После того, как вы получили, что из пути, я думаю, что это достаточно легко указать сервер так:

/(\w+)/ 

следующая часть просто все остальное, так что модель может быть сцеплены вместе, как:

/((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d+)\s+(\d\d:\d\d:\d\d)\s+(\w+)\s+(.*)/ 

И вы можете хранить эти данные в Perl этого выражения:

my ($date, $time, $host, $desc) 
    = $str =~ m/((?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d+) 
       \s+(\d\d:\d\d:\d\d)\s+(\w+)\s+(.*) 
       /x 
    ; 
+0

Благодарим вас за ответ! – Freddiboy

0

Следует отметить, что сравнение производительности между разъемным или готовыми регулярными выражениями (в выходе ниже: re1 от Axeman и RE2 упрощается /(\S+ \S+) (\S+) (\S+) (.*)/) подтверждает, что split выигрывает, но разница крошечная, вы даже не заметите это на менее чем миллионных строк. Axge regexp можно было бы улучшить, чтобы помочь вам доказать правильность вашего ввода, что очень важно.

10млн итерации сравнения:

 Rate re1 re2 spl 
re1 250000/s -- -28% -57% 
re2 344828/s 38% -- -41% 
spl 584795/s 134% 70% -- 

Вот краткое изложение на 100 млн звонков на древнем Core Duo:

re1: 40 wallclock secs (39.84usr+0.00sys=39.84CPU) @ 251004.02/s (n=10000000) 
re2: 29 wallclock secs (29.04usr+0.01sys=29.05CPU) @ 344234.08/s (n=10000000) 
spl: 18 wallclock secs (16.77usr+0.00sys=16.77CPU) @ 596302.92/s (n=10000000) 

Это выглядит существенным при этом количестве записей. Но если вы где-нибудь проверите достоверность говорящего остатка строки данных, вам лучше проверить его один раз на этапе синтаксического анализа.

Смежные вопросы