He estado usando std::regex_iterator
para analizar archivos de registro. Mi programa ha funcionado bastante bien durante algunas semanas y ha analizado millones de líneas de registro, hasta hoy, cuando hoy lo ejecuté contra un archivo de registro y recibí un desbordamiento de la pila. Resultó que solo una línea de registro en el archivo de registro estaba causando el problema. ¿Alguien sabe por qué mi expresión regular está causando una recursión tan masiva? Aquí hay un pequeño programa autónomo que muestra el problema (mi compilador es VC2012):¿Por qué std :: regex_iterator causa un desbordamiento de pila con estos datos?
#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;
}
El modelo parte compleja parece estar causando. No sé por qué sin embargo. –
Apuesto a que está bien en Perl, aún no confío en 'std :: regex'. – Benj
@Benj Wut? FUD. Puede ser una expresión regular exponencialmente mala. La mayoría de las veces se trata de estrellas kleene anidadas. Intente utilizar coincidencias no codiciosas y/o usando '+' en vez de '*' donde sea posible. También tenga cuidado con los opcionales en grupos repetidos. El mejor consejo ... Comience pequeño. Construya paso a paso. Pon a prueba tu expresión regular en cada paso. – sehe