Что не так с моим регулярным выражением? - PullRequest
0 голосов
/ 19 октября 2011

Я использую System::Text::RegularExpressions::Regex, чтобы попытаться найти сообщение о запуске в файле журнала. Мое выражение выглядит следующим образом:

using namespace System::Text::RegularExpressions;
Regex^ logStartRegex = gcnew Regex( "^=+ .* \\((\\d+)/(\\d+)/(\\d+) @ (\\d+):(\\d+):(\\d+)\\) (.*) =+", static_cast<RegexOptions>(RegexOptions::Compiled | RegexOptions::IgnoreCase) );

... и мои тестовые данные:

========= Logging started (07/10/2011 @ 15:38:54) v1.000 AA000 =========

... но когда я делаю следующее, я не вижу совпадения:

logStartRegex->Match( "========= Logging started (07/10/2011 @ 15:38:54) v1.000 AA000 =========\n" );

Я тестировал его в regexpal , что указывает на его работоспособность (обратите внимание, что в версии C ++ мы должны экранировать все символы \): ^=+ .* \((\d+)/(\d+)/(\d+) @ (\d+):(\d+):(\d+)\) (.*) =+ Есть ли способ узнать, где именно это сломалось?

Ответы [ 2 ]

1 голос
/ 19 октября 2011

Я считаю, что это должно следовать соглашениям для .Net Framework Regular Expression Flavor, хотя я не очень хорошо знаю C ++ ... если нет, то больше склоняется к реализации и API Java и похож на метод [Regex] Matcher.matches(), он попытается сопоставить регулярное выражение со всем источником (если он не соответствует всему источнику, но, возможно, соответствует только его части, попытка не удастся). Вызов .Net для функции Regex.Match() вызовет Найти выражение в указанном входе и вернет true, если найдено

Это был длинный способ сказать: убедитесь, что во входной строке нет пробелов или других символов.

Еще одно замечание - если ваш ввод на самом деле состоит из нескольких строк, особенно если другие строки содержат даты и время в скобках () - ваше выражение содержит жадные квантификаторы, примененные к классу точечных символов ".", который по крайней мере заставьте его работать ОЧЕНЬ МЕДЛЕННО для больших входных данных, если не как-то отключить его и заставить его не работать

В любом случае вы можете сделать свое выражение немного более эффективным, изменив экземпляры с .* на [^(]* и [^=]*, соответственно, следующим образом:

"^=+ [^(]* \\((\\d+)/(\\d+)/(\\d+) @ (\\d+):(\\d+):(\\d+)\\) ([^=]*) =+"

Жадные квантификаторы, которые вы бы заменили, в противном случае соответствовали бы всей строке много раз, а затем возвращались многократно, только чтобы, наконец, вернуться на место через десять или двадцать символов после того, как он начал говорить «о, хорошо, это соответствует ...» что дальше? "

1 голос
/ 19 октября 2011

Я только что попробовал следующую программу, скопированную из предоставленной вами информации:

using namespace System;
using namespace System::Text::RegularExpressions;

int main(array<System::String ^> ^args)
{
   Regex^ logStartRegex = gcnew Regex( "^=+ .* \\((\\d+)/(\\d+)/(\\d+) @ (\\d+):(\\d+):(\\d+)\\) (.*) =+", static_cast<RegexOptions>(RegexOptions::Compiled | RegexOptions::IgnoreCase) );
   Match^ match = logStartRegex->Match( "========= Logging started (07/10/2011 @ 15:38:54) v1.000 AA000 =========\n" );
   Console::WriteLine(match->Success);
   Console::ReadKey();    
   return 0;
}

Она выводит True на экран, означая, что найдено совпадение.Поэтому я полагаю, что проблема должна быть где-то еще в вашей программе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...