gpt4 book ai didi

c++ - 为什么 std::regex_iterator 会导致此数据的堆栈溢出?

转载 作者:可可西里 更新时间:2023-11-01 18:37:08 24 4
gpt4 key购买 nike

我一直在使用 std::regex_iterator 来解析日志文件。我的程序已经运行了几个星期并且已经解析了数百万行日志,直到今天,当今天我针对日志文件运行它并出现堆栈溢出时。事实证明,只有日志文件中的一个日志行导致了问题。有谁知道为什么我的正则表达式会导致如此大规模的递归?这是一个显示问题的独立小程序(我的编译器是 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;
}

最佳答案

在每个角色上测试的负前瞻模式对我来说似乎是个坏主意,而你想要做的并不复杂。您想要匹配 (1) 行的其余部分,然后 (2) 以 L\d 以外的其他内容开头的任意数量的以下 (3) 行(小错误;见下文):(另一个编辑:这些是正则表达式;如果你想将它们写成字符串文字,你需要将 \ 更改为 \\。)

 .*\n(?:(?:[^L]|L\D).*\n)*
| | |
+-1 | +---------------3
+---------------------2

在 Ecmascript 模式下,. 不应匹配\n,但您始终可以将表达式中的两个 . 替换为 [^\n]

编辑添加:我意识到如果在日志条目末尾之前有一个空行,这可能不起作用,但这应该涵盖这种情况;我将 . 更改为 [^\n] 以提高精度:

 [^\n]*\n(?:(?:(?:[^L\n]|L\D)[^\n]*)?\n)*

关于c++ - 为什么 std::regex_iterator 会导致此数据的堆栈溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12828079/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com