RegexKitLite не соответствует, Perl-поддерживаемые шашки
Я использую RKL в приложении Какао, чтобы разобрать операторы журнала из обернутой задачи.
Шаблон:
(?:.+) \[.+?\] (.+) \[.+?\] logged in (?:.+)
Тестовые данные:
2011-07-11 00:48:19 [INFO] Preparing spawn area: 97
2011-07-11 00:48:19 [INFO] Done (2175837000ns)! For help, type "help" or "?"
2011-07-11 00:48:42 [INFO] mikeyward [/127.0.0.1:59561] logged in with entity id blahblah
Каждый тестер RegEx, который я пробовал в Интернете, успешно соответствует третьей строке и записывает "mikeyward".
Код Objective-C:
NSString *loggedInPattern = @"(?:.+) \\[.+?\\] (.+) \\[.+?\\] logged in (?:.+)";
NSArray *captures = [searchString arrayOfCaptureComponentsMatchedByRegex:loggedInPattern];
NSString *username = [captures objectAtIndex:0];
Проблема: Несмотря на проверку того, что searchString действителен и содержит примеры данных, RKL не соответствует строке, не говоря уже о захвате имени пользователя. В приведенном выше примере выдается исключение, потому что массив captures возвращается с нулевыми объектами, а я не проверяю ошибки:)
Буду очень признателен за любую помощь в понимании того, почему контролеры регулярных выражений подтверждают совпадение и захват, но RKL пропускает его
Благодаря ~
2 ответа
Ваша проблема может быть связана с этой, или это может быть просто случай катастрофического возврата. Мой совет будет одинаковым в любом случае: напишите регулярное выражение, чтобы ни один из квантификаторов не имел перекрывающихся интервалов влияния. Например:
(?m)^[ 0-9:-]+\[[A-Z]+\] (\S+) \[[^\]]+\] logged in .+$
В вашем регулярном выражении первый (?:.+)
первоначально сожирает все символы в строке, только чтобы вернуть большинство из них, чтобы у остальных регулярных выражений был шанс совпадать. [ 0-9:-]+
с другой стороны, перестает потреблять, как только видит символ, который не является пробелом, цифрой, двоеточием или дефисом.
Если следующий символ не [
это не идет дальше, и общая попытка матча проваливается намного быстрее, чем это было бы раньше. Так же, [A-Z]+
не может пройти мимо закрытия ]
, \S+
не может заполнить следующий пробел, и [^]] +stops before the next
]. I didn't change the final
. + `потому что он уже делает то, что нам нужно, т. е. потребляет все символы до следующего символа новой строки или конца текста.
Вот как бы я написал регулярное выражение в любом случае, но просто из любопытства, что произойдет, если вы оставите регулярное выражение таким, как есть, но добавите якоря строк?
(?m)^(?:.+) \[.+?\] (.+) \[.+?\] logged in (?:.+)$
Это все еще ужасно неэффективно, но это может иметь значение между неработающей и плохой работой.:D
Ваш сопоставитель выполняет сопоставление только одной строки. Используйте версию с опциями и передайте ее RKLMultiline