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

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