Кстати, задачка:
Практическая задачка по программированию на Perl.
Необходимо парсить строки из лог-файлов прокси-сервера, и разбивать их на поля.
Поля обычно разбиваются одиночными пробелами -- однако, когда в поле содержатся пробелы, оно целиком заключается в двойные кавычки.
Понятно, что при разборе кавычки надо убрать.
Вот пример трех строк из лога:
Особо долго думать над этим было лень -- сделал примерно так:
Оно работает (и, вроде, с вполне приемлимой скоростью). Но все-таки интересно: можно ли придумать решение получше?
Необходимо парсить строки из лог-файлов прокси-сервера, и разбивать их на поля.
Поля обычно разбиваются одиночными пробелами -- однако, когда в поле содержатся пробелы, оно целиком заключается в двойные кавычки.
Понятно, что при разборе кавычки надо убрать.
Вот пример трех строк из лога:
95.221.133.164 [14/Apr/2019:03:38:06 +0300] "infoculture.rsl.ru:80" "GET /NIKLib/home/home.css HTTP/1.1" 200 1740 0.013 "http://infoculture.rsl.ru/donArch/home/news/dek/2002/07/2002-07_r_dek-s3.htm" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0" 95.221.133.164 [14/Apr/2019:03:38:06 +0300] "infoculture.rsl.ru:80" "GET /NIKLib/shared/js/utils.js HTTP/1.1" 404 2505 0.001 "http://infoculture.rsl.ru/donArch/home/news/dek/2002/07/2002-07_r_dek-s3.htm" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0" 95.221.133.164 [14/Apr/2019:03:38:07 +0300] "infoculture.rsl.ru:80" "GET /NIKLib/home/images/bgr_4021.gif HTTP/1.1" 404 2510 0.001 "http://infoculture.rsl.ru/donArch/home/news/dek/2002/07/2002-07_r_dek-s3.htm" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0"
Особо долго думать над этим было лень -- сделал примерно так:
sub Split_PX_line {
my $src = shift;
my $inx = length ($src);
my ($at0, $at1);
my @res;
while (
($at1 = rindex ($src, '"', $inx - 1)) >= 0
&&
($at0 = rindex ($src, '"', $at1 - 1)) >= 0
) {
unshift (@res, split (' ', substr ($src, $at1 + 1, $inx - $at1 - 1)))
if ($inx - $at1 >= 2);
unshift (@res, substr ($src, $at0 + 1, $at1 - $at0 - 1));
$inx = $at0;
}
unshift (@res, split (' ', substr ($src, 0, $inx - 1)));
return @res;
} # Split_PX_line
Оно работает (и, вроде, с вполне приемлимой скоростью). Но все-таки интересно: можно ли придумать решение получше?