Использование ленивых вычислений для большого регулярного выражения (и не только.*?)

Используя следующее регулярное выражение:

\[\w* \w* \d{2} [\w:]* \d{4}\] \[error\] \[client .*?\] .*? Using HTTP not .*?<br /> 

Я получаю следующие результаты (где желтые прямоугольники указывают на совпадение):

Возвышенный текст 2

Необработанный текст: http://pastebin.com/vSi0mLGv

Два нижних раздела правильные. Я хочу, чтобы все разделы, которые содержат: &lt;&lt;&lt;NOTICE&gt;&gt;&gt; Non-Prod Server: Using HTTP not HTTP/S

Верхний раздел, однако, содержит правильную строку (аналогичную двум нижним), но также поставляется с другим блоком, который мне не нужен:

[Thu May 10 17:43:48 2012] [error] [client ::1] Current Name:
DashboardBar_projAnnualReview200, referer: http://
localhost/test/pages/TestPage.php<br />`

Я знаю, что это сводится к тому, чтобы регулярное выражение было жадным, но как я могу заставить его делать ленивую оценку для <br />, если это даже правильный путь. я пробовал (<br />)*? и другие безрезультатно.


Другая информация: я использую Sublime Text 2 и выполняю поиск по регулярному выражению, если кто-то хочет воссоздать изображение.

2 ответа

Решение

Жадность не проблема, рвение есть. Движок регулярных выражений начинает пытаться сопоставить при первой же возможности, и он не сдается, пока не исчерпаны все возможности. Отсутствие жадности в квантификаторах не меняет этого, оно просто меняет порядок, в котором пробуются возможности.

Это не * в .* это вызывает вашу проблему, это ., Вам нужно использовать что-то более ограничительное, потому что это позволяет начать матч слишком рано. Это регулярное выражение работает как хотелось бы, потому что я заменил .*? с [^][]*, который соответствует любым символам, кроме ] или же [:

\[\w* \w* \d{2} [\w:]* \d{4}\] \[error\] \[client [^][]*\] [^][]* Using HTTP not .*?<br />

Я не знаю, что использует регулярное выражение SublimeText, так что вам может понадобиться экранировать квадратные скобки внутри класса символов:

\[\w* \w* \d{2} [\w:]* \d{4}\] \[error\] \[client [^\]\[]*\] [^\]\[]* Using HTTP not .*?<br />

Вы имеете в виду "неохотно", а не "ленивый".

Там не должно быть никакого вмешательства <br />, право? Что-то вроде ((?!<br />).)* может работать.

Другие вопросы по тегам