Używam std::regex_iterator
do analizowania plików dziennika. Mój program działa całkiem ładnie od kilku tygodni i przeanalizował miliony wierszy dziennika, do dziś, kiedy dziś uruchomiłem go w pliku dziennika i uzyskałem przepełnienie stosu. Okazało się, że przyczyną problemu był tylko jeden wiersz dziennika w pliku dziennika. Czy ktoś wie, dlaczego moje regex powoduje tak masową rekursję? Oto mały autonomiczny program, który pokazuje problem (mój kompilator jest VC2012):Dlaczego std :: regex_iterator powoduje przepełnienie stosu tymi danymi?
#include <string>
#include <regex>
#include <iostream>
using namespace std;
std::wstring test = L"L3 T15356 79726859 [CreateRegistryAction] Creating REGISTRY Action:\n"
L" Identity: 272A4FE2-A7EE-49B7-ABAF-7C57BEA0E081\n"
L" Description: Set Registry Value: \"SortOrder\" in Key HKEY_CURRENT_USER\\Software\\Hummingbird\\PowerDOCS\\Core\\Plugins\\Fusion\\Settings\\DetailColumns\\LONEDOCS1\\Search Unsaved\\$AUTHOR.FULL_NAME;DOCSADM.PEOPLE.SYSTEM_ID\n"
L" Operation: 3\n"
L" Hive: HKEY_CURRENT_USER\n"
L" Key: Software\\Hummingbird\\PowerDOCS\\Core\\Plugins\\Fusion\\Settings\\DetailColumns\\LONEDOCS1\\Search Unsaved\\$AUTHOR.FULL_NAME;DOCSADM.PEOPLE.SYSTEM_ID\n"
L" ValueName: SortOrder\n"
L" ValueType: REG_DWORD\n"
L" ValueData: 0\n"
L"L4 T15356 79726859 [CEMRegistryValueAction::ClearRevertData] [ENTER]\n";
int wmain(int argc, wchar_t* argv[])
{
static wregex rgx_log_lines(
L"^L(\\d+)\\s+" // Level
L"T(\\d+)\\s+" // TID
L"(\\d+)\\s+" // Timestamp
L"\\[((?:\\w|\\:)+)\\]" // Function name
L"((?:" // Complex pattern
L"(?!" // Stop matching when...
L"^L\\d" // New log statement at the beginning of a line
L")"
L"[^]" // Matching all until then
L")*)" //
);
try
{
for (std::wsregex_iterator it(test.begin(), test.end(), rgx_log_lines), end; it != end; ++it)
{
wcout << (*it)[1] << endl;
wcout << (*it)[2] << endl;
wcout << (*it)[3] << endl;
wcout << (*it)[4] << endl;
wcout << (*it)[5] << endl;
}
}
catch (std::exception& e)
{
cout << e.what() << endl;
}
return 0;
}
Kompleks część wzór wydaje się być przyczyną tego. Nie wiem dlaczego. –
Założę się, że jest w porządku w perlu, nie całkiem ufam 'std :: regex' jeszcze. – Benj
@Benj Wut? FUD. Może to być wyrażenie regularne niepoprawnie wykładające. Najczęściej dotyczy to nested kleene stars. Spróbuj użyć nie-chciwych dopasowań i lub, jeśli to możliwe, użyj '+' zamiast '*'. Uważaj także na opcje w powtarzających się grupach. Najlepsza rada ... Zacznij od małej. Buduj krok po kroku. Przetestuj swoje wyrażenie regularne na każdym kroku. – sehe