私はstd::regex_iterator
ログファイルを解析するために使用してきました。私のプログラムは数週間非常にうまく機能しており、今日までログファイルに対して実行してスタックオーバーフローが発生するまで、何百万ものログ行を解析してきました。ログファイルの1行だけが問題の原因であることが判明しました。なぜ私の正規表現がそのような大規模な再帰を引き起こしているのか知っている人はいますか?これが問題を示す小さな自己完結型プログラムです(私のコンパイラはVC2012です):
#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;
}