Python-Script перестает работать при прохождении через регулярное выражение - PullRequest
0 голосов
/ 25 марта 2011

У меня большой текстовый файл, и я обрабатываю его построчно, используя оператор for ... in:

f = open(sys.argv[1])
for line in f:

И я пропускаю эти строки через некоторые регулярные выражения. Но мой код останавливается, когда эта длинная строка проходит через регулярное выражение: Это строка:

Mar 25 09:42:22 2011 amavis[30883]: (30883-10) Passed CLEAN, [95.0.85.202] [95.0.85.202] <oyalcin@aaa.com> -> <acanli@aaa.com.tr>,<aeren@aaa.com.tr>,<aergul@aaa.com.tr>,<dalp@aaa.com.tr>,<faks@aaa.com.tr>,<fkonyali@aaa.com.tr>,<hozsoy@aaa.com.tr>,<makcan@aaa.com.tr>,<mengin@aaa.com.tr>,<mervekayabasi@aaa.com.tr>,<muhasebe@aaa.com.tr>,<okkesgol@aaa.com.tr>,<personel@aaa.com.tr>,<skazanci@aaa.com.tr>,<sumur@aaa.com.tr>,<tkececioglu@aaa.com.tr>,<ydemirci@aaa.com.tr>,<abalcin@aaa.com>,<adanisti@aaa.com>,<akaramanli@aaa.com>,<aozsahin@aaa.com>,<benalin@aaa.com>,<cgokburun@aaa.com>,<dkilinc@aaa.com>,<gleblebici@aaa.com>,<hsannan@aaa.com>,<iziyan@aaa.com>,<kcspetrol@aaa.com>,<malakus@aaa.com>,<maltuntas@aaa.com>,<mdelice@aaa.com>,<mguclu@aaa.com>,<mkocyigit@aaa.com>,<mokuducu@aaa.com>,<mtabar@aaa.com>,<m...

И это регулярное выражение и место, где код останавливается:

pattern_clean = re.compile("(\S{3} \d{2} \d{2}\:\d{2}\:\d{2} \d{4}).*CLEAN, (LOCAL )?(\[[.\d]+\] )?(\[[.\d]+\] )?<(\S*@(\S*))?> -> (<\S*>,)* Message-ID: <(\S*)>, mail_id: (\S*), Hits: (\S*), queued_as: (\S*), (\S*)")

if pattern_clean.search(line) != None:

Я пробовал этот скрипт в другом файле, он работал нормально. С этим файлом тоже все работало нормально, пока не пришла эта строка. Что может быть причиной этой проблемы?

Ответы [ 2 ]

4 голосов
/ 25 марта 2011

Можно написать регулярные выражения, которые очень или очень долго либо совпадают, либо терпят неудачу. Вы написали именно такое регулярное выражение. По сути, всякий раз, когда вы видите * или +, вложенный в другое * или +, очень бойтесь.

Я думаю, что ваша проблема может быть:

(<\S*>,)*

Сам по себе, <\S*> будет сопоставлять все до следующего пробела, затем, когда полный шаблон не будет совпадать, он попытается сократить совпадение, тогда внешний * означает, что он попробует множество различных комбинаций. сопоставление 20 электронных писем, за которыми не следует ни одного, или 19, за которыми следует 1, или 18, за которыми следуют 2 или 18, за которыми следует 1, за которым следует 1. У вас есть убегающие комбинации.

Я предлагаю вам попробовать заменить все ваши \S вхождения шаблоном, который не может соответствовать завершающему символу. например <[^> ]*> или [^, ]*,, которые могут уменьшить проблему.

0 голосов
/ 25 марта 2011

Я не эксперт в регулярных выражениях Python, но некоторые общие замечания

У вас много якорей, поэтому жадные квантификаторы подходят почти везде, кроме одного места.

(<\S*>,)* Этоне будет делать то, что, как вы думаете, будет.

По сути, группа будет выполняться только 0 или 1 раз, поэтому она действительно выполняет (<\S*>,)?.
И матч будет развиваться следующим образом:

<aergul@aaa.com.tr>, ... <dalp@aaa.com.tr>,
^       ^^^^^^^^^^^^^^^^^^^^^^^^^^^          ^^
<               \S*                          >,

Он не собирается захватывать с использованием произвольного числа групп захвата.
Функционально эквивалентен (и лучше записан как) этому:

((?:<\S*?>,)+)?

Я протестировал (<\S*>,)* с предоставленной вами выборкой данных.Работает нормально в Perl.Но я могу только предположить, что ваши данные выходят далеко за рамки того, что вы показываете.Просто осознайте, что вы захватываете все до следующего большого якоря >, Message-ID: в одном выражении.

Это может быть переписано как:
(<\S*?>,)*, который просто сохраняет последний <>, в серии, гдескобки относятся только к группам без захвата.

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