Sto usando std::regex_iterator
per analizzare i file di registro. Il mio programma ha funzionato abbastanza bene per alcune settimane e ha analizzato milioni di righe di log, fino a oggi, quando oggi l'ho eseguito su un file di log e ottenuto un overflow dello stack. Si è scoperto che solo una riga di registro nel file di registro causava il problema. Qualcuno sa perché la mia espressione regolare sta causando una così grande ricorsione? Ecco un programma contenuto piccola auto che mostra il problema (il mio compilatore è VC2012):Perché std :: regex_iterator causa uno stack overflow con questi dati?
#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;
}
La parte complesso schema sembra essere la causa di esso. Non so perché però. –
Scommetto che va bene in perl, non mi fido abbastanza di 'std :: regex' ancora. – Benj
@ Ben Wut? FUD. Può essere un'espressione regolare in modo esponenziale. Molto spesso si tratta di stelle kleene annidate. Prova a usare corrispondenze non avide e o usando '+' invece di '*' dove possibile. Fai attenzione anche agli optionals in gruppi ripetuti. Il miglior consiglio ... Inizia in piccolo. Costruisci passo dopo passo. Metti alla prova la tua espressione regolare ogni fase. – sehe