c++ - 如何将 std::regex_search 与超过 497 个字符的 wstring 一起使用?

标签 c++ regex visual-studio

我目前正在开发一个使用正则表达式匹配特定 URL 的程序。比如我有这个案例:

int main()
{
    try 
    {
        std::wstring url = L"www.google.com";
        std::wregex reg(L"^(?:(?!math|latex).)*\\.?stackexchange.com");
        std::regex_search(url, reg);
    }
    catch (std::regex_error e)
    {
        std::cout << e.what() << std::endl;
        std::cout << e.code() << std::endl;
    }
}

很有魅力,在这种情况下它显然不匹配。但是,如果我使用任何长度超过 497 个字符的 url 字符串,则 regex_search 函数将失败。示例:

std::wstring url = L"AAAAA...AAAA"; //498 chars long

e.what() 打印:“regex_error(error_stack):内存不足,无法确定正则表达式是否可以匹配指定的字符序列。”

e.code() 输出:12

令我惊讶的是,堆栈大小似乎是问题所在。毕竟,如果您考虑使用正则表达式搜索文件或网站源代码,498 个字符并不算多。除了将问题延迟到更多(可能 1000 个)字符之外,是否有任何方法可以可靠地解决此问题?也许有一个自写的分配器?尽管我怀疑是否有可能提供任何形式的分配器来在堆上分配堆栈帧。增加堆栈大小不是真正的解决方案,因为它只会延迟问题。

我使用的是 Visual Studio Community 2017,版本 15.5.6。

这表明我的假设似乎是正确的。

确切异常:RegTest.exe 中 0x76EECBB2 处的未处理异常:Microsoft C++ 异常:内存位置 0x00454FF8 处的 std::regex_error。

最佳答案

这里的问题是标准没有指定 std::regex_search 的实现。

一个好的实现会注意到正则表达式最重要的部分是它的后半部分。 stackexchange.com" 是一个很好的匹配模式。一旦找到,就很容易检查前面是什么。

不过,一个简单的实现将按照编写的顺序使用您的正则表达式。它将首先匹配 ^,这当然会在任何输入时立即发生。然后它得到一个 (?:(?!math|latex).)*,这是最难匹配的模式之一。这不是一个正式的正则表达式,而是一个否定的前瞻,后跟通配符匹配 .,然后重复 *

如评论中所述,正则表达式匹配在形式上是贪婪的。天真的正则表达式引擎将忽略最后的 stackexchange.com 部分并反复尝试匹配 (?:(?!math|latex).)*,每次都成功那部分只会在 stackexchange.com 上失败。

解决方法是你自己要聪明,按照你认为最好的顺序进行字符串解析。首先通过简单的 string::find 匹配 .stackexchange.com,而不是通过正则表达式。只有在这种情况下,通过 regex_search 检查子域部分,并使用更简单的表达式。

关于c++ - 如何将 std::regex_search 与超过 497 个字符的 wstring 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49148295/

相关文章:

visual-studio - 如何在 Visual Studio 中使用 XAML 2009 作为设计数据?

c++ - 我怎样才能让我的 linux 服务触发我的信号?

c++ - IntelMPI 错误(适用于 openMPI)

python - 如何在 python 中将字符串拆分为列表并将两个已知标记合并为一个?

regex - Linux bash : sed, awk 等工具将行尾正则表达式 '$' 匹配为终端宽度

c# - gitignore 文件可以具有 XML 文档文件的通用模式吗?

c++ - “稳定”的多维缩放算法

c++ - 现有的纯 C++ 类是否可以在不转换为 COM 类的情况下实现 IDL 接口(interface)?

.net - Look around 未通过 .net 提供预期结果

c# - 带有 Xamarin 的 Handlebars.net 在 Release 中不起作用