Regex занимает слишком много времени, чтобы соответствовать результату - PullRequest
2 голосов
/ 29 декабря 2010

У меня есть этот шаблон регулярных выражений

<(\d+)>(\d+\.\d+|\d{4}\-\d+\-\d+\s+\d{2}:\d{2}:\d{2})(?:\..*?)*\s+(ALER|NOTI)

и это мой ввод (не будет соответствовать вообще)

<150>2010-12-29 18:11:30.883 -0700 192.168.2.145 80 192.168.2.87 2795 "-" "-" GET HTTP 192.168.2.145 HTTP/1.1 200 36200 0 1038 544 192.168.2.221 80 540  SERVER DEFAULT PASSIVE VALID /joomla/ "-" http://192.168.2.145/joomla/index.php?option=com_content&view=a be4d44e8f3986183a87991398c1c212e=1;      be4d44e8f3986183a87991398c1c212e=1

Это вернет несоответствующий результат, но для вывода результата потребуется слишком много времени. Так как у меня есть тысяча журналов / входов в секунду, он должен заканчиваться очень быстро для каждого отдельного журнала / ввода. Иногда он достигает CPU 100%.

Может кто-нибудь помочь мне решить эту проблему регулярных выражений?

Спасибо

Ответы [ 3 ]

8 голосов
/ 29 декабря 2010

У вас катастрофический откат назад из-за большого количества способов, которыми может совпадать выражение (?:\..*?)* Потенциально миллионы совпадений должны быть проверены, увеличиваясь по экспоненте с количеством точек в вашей строке. Чтобы исправить это, вы можете изменить это:

(?:\..*?)*\s+

к этому:

\..*\s
3 голосов
/ 29 декабря 2010

Похоже, вы ищете какую-то дату / время / и т.д. информация о линиях ALER / NOTI. Разве вы не можете только проанализировать эти строки, сначала отключив ALER / NOTI? Тогда, вероятно, было бы намного проще запустить регулярное выражение в этих интересных строках (и это, вероятно, упростило бы регулярное выражение).

2 голосов
/ 30 декабря 2010

Так как вы не предоставили рабочий пример, единственное, что нужно сказать, почему его медленный
- это (?:\..*?)*, что странно.Мета-период.соответствует всему, включая буквальный
период.Это выражение говорит, что если есть буквальный период, получите его и все до \ s.
Но буквальный период не является обязательным.

(?:\.(?:(?!\s(?:ALER|NOTI)).)*?)?\s+(ALER|NOTI)

Что само по себе довольно странно.Его можно просмотреть, если развернуть.

(?:
    \.
    (?:
        (?!\s(?:ALER|NOTI)).
    )*?
)?
\s+
(ALER|NOTI)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...