LINUX.ORG.RU

Помогите пофиксить regexp

 , ,


1

1

Призываю джедаев Perl'а.

Есть avavis-new версии 2.10.0. Собственно одна из его задач — распаковывать архивы и передавать их антивирусу. В логах ошибка

(!)do_unrar: can't parse info line for .....
Покопавшись в коде выяснилось что там неработающая регулярка.
# amavisd:30296
/^ ([* ]) \s+ \S+ \s+ (\d+) \s+ (\d+) \s+ ( \d+ % | --> | <-- | <-> ) \s+ \S+ \s+ \S+ \s+ \S+ \s+ (.*)/xs
Вот строки которые отдает ему unrar v -c- -p- -idcdp — test.rar при запароленом архиве:
*-rw-rw-r--      2760      1920  69%  30-09-14 11:33  8EF1D373  a.txt
Архив без пароля:
 -rw-rw-r--    496640    179100  36%  30-09-14 21:54  0647CF31  tttt.exe    \n

Я не особо разбираюсь в регулярках, особенно в перловских. Подскажите как поправить.

PS. Если убрать первое '\s+' после группы ([* ]), то начинает почти(!) парсить строку, кроме последней группы. Туда попадают пробелы, \n, и следующие строки.

★★

Последнее исправление: greek_31 (всего исправлений: 2)

не особо разбираюсь в регулярках, особенно в перловских.

pcre это вообще то стандарт регекспов, наряду с упрощенными bre

/^ ([* ]) \s+ \S+

Начало строки, звёздочка или пробел, один или более пробел, один или более символов

*-rw-rw-r--

нет пробела после звёздочки

Можешь попробовать заменить начало регулярки на /^ ([* ]) \s* \S+

Возможно дальше еще ошибки, не читал

disarmer ★★★
()
Ответ на: комментарий от disarmer

Можешь попробовать заменить начало регулярки на /^ ([* ]) \s* \S+

Да я так и сделал. Скорее всего это даже правильно.

Также пофиксил конец строки так: '(.*)' => '(\S+) И имена файлов начали нормально падать в пятую группу без пробелом в \n

Вопрос к джедаям теперь: «Всё ли правильно я сделал?» =)

UPD. unrar отдаёт еще 1 вид строки:

    ..A....    496640    225967  45%  30-09-14 21:54  0647CF31  filename.txt

greek_31 ★★
() автор топика
Последнее исправление: greek_31 (всего исправлений: 1)
Ответ на: комментарий от greek_31

Если файл будет с пробелом в имени, то (\S+) поймает только первую часть до пробела. Чтобы пробел не попадал, можно заменить на (.*?)\s*$

\n можно обрезать с помощью chomp($str)

disarmer ★★★
()
Последнее исправление: disarmer (всего исправлений: 1)
Ответ на: комментарий от disarmer

Работает с пробелами. Спасибо.

chomp вроде где-то далее по коду вызывается

greek_31 ★★
() автор топика
Ответ на: комментарий от disarmer

Можешь попробовать заменить начало регулярки на /^ ([* ]) \s* \S+

А какой смысл тогда в \s? Не проще ли поставить .* тогда уж?

linux-101
()
Ответ на: комментарий от disarmer

заменить на /^(*?).+

Да, но тогда нарушается условие «звездочка или пробел в начале строки затем 1 или более пробельных символов, затем один или более непробельных символов, затем опять один или более пробельных символов». Спрашивается, нахрена они поставили эту маску там в оригинале, не просто так, ради прикола, надо полагать?

linux-101
()
Ответ на: комментарий от linux-101

Нужно же узнать потом, была ли в начале звёздочка. Если была, то она останется в первой группе ($1), иначе группа будет пуста.

Только я ошибся, звёздочку надо экранировать: /^(\*?).+

disarmer ★★★
()
Ответ на: комментарий от disarmer

Да, я как раз об этом, не понял, что имелось в виду, теперь ясно.

linux-101
()

Можно вопрос разработчика задать: почеме не используется в 10 раз быстрая функция split?

my ($flags, $size, $packsize, $pt, $date, $hash, $name) =
    split /\s+/, $string;

gh0stwizard ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.