c++ - 为什么 boost 正则表达式用完了堆栈空间?

标签 c++ regex boost boost-regex

#include <boost/regex.hpp>
#include <string>
#include <iostream>

using namespace boost;
static const regex regexp(
        "std::vector<"
            "(std::map<"
                   "(std::pair<((\\w+)(::)?)+, (\\w+)>,?)+"
             ">,?)+"
        ">");

std::string errorMsg =
"std::vector<"
        "std::map<"
                "std::pair<Test::Test, int>,"
                "std::pair<Test::Test, int>,"
                "std::pair<Test::Test, int>"
        ">,"
        "std::map<"
                "std::pair<Test::Test, int>,"
                "std::pair<Test::Test, int>,"
                "std::pair<Test::Test, int>"
        ">"
">";
int main()
{
    smatch result;
    if(regex_match(errorMsg, result, regexp))
    {  
        for (unsigned i = 0; i < result.size(); ++i)
        {  
            std::cout << result[i] << std::endl;
        }
    }

//    std::cout << errorMsg << std::endl;

    return 0;
}

这会产生:

terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::runtime_error>
>'   what():  Ran out of stack space trying to match the regular expression.

编译为

g++ regex.cc -lboost_regex

编辑

我的平台:

g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
libboost-regex1.42
Intel(R) Core(TM)2 Quad CPU Q9400 @ 2.66GHz
So the latest Ubuntu 64 bit

最佳答案

((\\w+)(::)?)+ 是所谓的“病态”正则表达式之一——它会花费指数时间,因为你有两个表达式一个接一个地互相依赖。也就是说,由于 catastrophic backtracking 而失败.

考虑我们是否遵循链接的示例,并将“更复杂的东西”减少为“x”。让我们用 \\w 来做到这一点:

  • ((x+)(::)?)+

我们还假设我们的输入永远不会有 ::。有了这个实际上会使正则表达式更加复杂,所以如果我们抛开复杂性,那么我们真的应该让事情变得更简单,如果没有别的:

  • (x+)+

现在您已经遇到了教科书式的嵌套量词问题,如上面链接中详述的那样。

有几种方法可以解决这个问题,但最简单的方法可能是使用 atomic group modifier 禁止在内部匹配中回溯。 "(?>":

  • ((?>\\w+)(::)?)+

关于c++ - 为什么 boost 正则表达式用完了堆栈空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4495733/

相关文章:

c++ - 如何为小数点分隔符和位数调整 std::stod(字符串加倍)

c# - 使用 BinaryReader 在 C# 中读取序列化的 C++ 结构

php preg_split 忽略特定字符串中的逗号

c++ - 在 boost 单位和持续时间之间转换

c++ - fedora 20 上的 boost/lexical_cast

c++ - C++中的静态数据成员

C++ 将带有十六进制字符的 .txt 转换为带有\x 的十六进制字符的 .text

python - 如何在ansible playbook中使用正则表达式排除单词?

javascript - 文本区域字符串 : limit to 1 empty line at a time

c++ - (C++ Boost) 在列表中查找成员与搜索词匹配的项目