Я должен не согласиться с предложениями других ответов использовать не жадные квантификаторы (т. Е. .*?
).Предполагая, что ]
не является допустимым символом в ваших полях time / error / who, вы не ищете кратчайшую возможную последовательность из любых символов вообще, за которой следует ]
.Вы ищете самую длинную последовательность не ]
символов, которая правильно записана как [^]]*
.Делать это таким образом более эффективно (механизм регулярных выражений может немедленно останавливаться, когда он видит ]
, вместо того, чтобы потенциально сделать много возвратов, чтобы найти альтернативные совпадения), и более точно передает ваши намерения будущим программистам, читающим код.
#!/usr/bin/env perl
use strict;
use warnings;
while (<DATA>) {
chomp;
my ($time, $err, $who, $mess) =
($_ =~/\[([^]]*)\] \[([^]]*)\] (?:\[([^]]*)\] )?(.*)/);
$who ||= '(unspecified)';
print "$time - $err - $who - $mess\n";
}
__DATA__
[time1] [error1] [who is1] mess is here1
[time2] [error2] mess is here2
Вывод:
time1 - error1 - who is1 - mess is here1
time2 - error2 - (unspecified) - mess is here2
Между прочим, основная проблема в вашем начальном регулярном выражении не была жадным совпадением, так или иначе ... Вы пытались сопоставить [.]*
, который будет соответствовать только последовательностямиз буквальных .
символов;он бы работал нормально для записи в журнале "[...] [..] [......] ..........", но не будет совпадать для записи, содержащейсимволы, отличные от разделителей []
, пробелы, разделяющие поля, и точки для содержимого полей.