Использование ленивых вычислений для большого регулярного выражения (и не только.*?)
Используя следующее регулярное выражение:
\[\w* \w* \d{2} [\w:]* \d{4}\] \[error\] \[client .*?\] .*? Using HTTP not .*?<br />
Я получаю следующие результаты (где желтые прямоугольники указывают на совпадение):
Необработанный текст: http://pastebin.com/vSi0mLGv
Два нижних раздела правильные. Я хочу, чтобы все разделы, которые содержат: <<<NOTICE>>> 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 />).)*
может работать.