Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 微软';std::regex的s实现_C++_Regex_C++11_Stack Overflow_Standard Library - Fatal编程技术网

C++ 微软';std::regex的s实现

C++ 微软';std::regex的s实现,c++,regex,c++11,stack-overflow,standard-library,C++,Regex,C++11,Stack Overflow,Standard Library,我一直在使用库(Microsoft Visual Studio 2012:Update 3),试图使用它为我的应用程序实现一个稍微安全的加载过程,并且在开始时遇到了一些困难(参见和) 通过使用建议的正则表达式,我已经解决了最初的问题(导致堆栈溢出等),并且一直运行良好;但是,如果我的文件太大,则会导致堆栈溢出(我通过增加堆栈提交和保留大小来规避此问题),或者如果堆栈大小足够大而不会导致堆栈溢出,则会导致std::regex\u error错误代码12(error\u stack) 下面是一个复制

我一直在使用
库(Microsoft Visual Studio 2012:Update 3),试图使用它为我的应用程序实现一个稍微安全的加载过程,并且在开始时遇到了一些困难(参见和)

通过使用建议的正则表达式,我已经解决了最初的问题(导致堆栈溢出等),并且一直运行良好;但是,如果我的文件太大,则会导致堆栈溢出(我通过增加堆栈提交和保留大小来规避此问题),或者如果堆栈大小足够大而不会导致堆栈溢出,则会导致
std::regex\u error
错误代码
12(error\u stack)

下面是一个复制该问题的自包含示例:

#include <iostream>
#include <string>
#include <regex>

std::string szTest = "=== TEST1 ===\n<Example1>:Test Data\n<Example2>:More Test Data\n<Example3>:Test\nMultiline\nData\n<Example4>:test_email@test.com\n<Example5>:0123456789\n=== END TEST1 ===\n=== TEST2 ===\n<Example1>:Test Data 2\n<Example2>:More Test Data 2\n<Example3>:Test\nMultiline\nData\n2\n<Example4>:test_email2@test.com\n=== END TEST2 ===\n=== TEST3 ===\n<Example1>:Random Test Data\n<Example 2>:More Random Test Data\n<Example 3>:Some\nMultiline\nRandom\nStuff\n=== END TEST3 ===\n\
                      === TEST1 ===\n<Example1>:Test Data (Second)\n<Example2>:Even More Test Data\n<Example3>:0123456431\n=== END TEST1 ===";

int main()
{
    static const std::regex regexObject( "=== ([^=]+) ===\\n((?:.|\\n)*)\\n=== END \\1 ===", std::regex_constants::ECMAScript | std::regex_constants::optimize );

    for( std::sregex_iterator itObject( szTest.cbegin(), szTest.cend(), regexObject ), end; itObject != end; ++itObject )
    {
        std::cout << "Type: " << (*itObject)[1].str() << std::endl;
        std::cout << "Data: " << (*itObject)[2].str() << std::endl;

        std::cout << "-------------------------------------" << std::endl;
    }
}
#包括
#包括
#包括
std::字符串测试="===TEST1==\n:测试数据\n:更多测试数据\n:测试\n多行\n数据\n:测试_email@test.com\n:0123456789\n===结束测试1==\n===测试2==\n:测试数据2\n:更多测试数据2\n:测试\n多行\n数据\n2\n:测试_email2@test.com\n===结束测试2==\n===结束测试3==\n:随机测试数据\n:更多随机测试数据\n:一些\n多行\n随机\n随机\n缓冲\n==结束测试3==\n\
===TEST1==\n:测试数据(秒)\n:更多测试数据\n:0123456431\n===END TEST1===”;
int main()
{
静态常量std::regex regexObject(“==([^=]+)===\\n((?:.| \\\\n)*)\\n===END\\1==”,std::regex_常量::ECMAScript | std::regex_常量::优化);
对于(std::sregex_迭代器itObject(szTest.cbegin(),szTest.cend(),regexObject),end;itObject!=end;++itObject)
{
std::cout忘记
–至少现在是这样,可能是好的。在我看来,规范已经被破坏,无法使用;但即使不是这样,至少当前的实现是,并且可能在未来几年都会如此

这是因为所有主要供应商都从零开始实现自己的正则表达式引擎,而不是依赖现有的、经过尝试和测试的库

我的建议是:现在就使用另一个正则表达式库,不要使用
。替代方法是,和(C风格)库,如或


顺便说一句,我们今天在聊天中讨论了这个话题。如果你有半个小时的时间,。

问题在于反向引用(
\1
)。反向引用是邪恶的,或者至少在一般情况下很难实现,并且不容易识别非一般情况

在您的例子中,问题是正则表达式的第一个匹配将是从第一个
====TEST1====
到最后一个
==END TEST1===
。这不是您想要的,而是正则表达式的工作方式。(最长的最左规则)理论上,在不破坏堆栈的情况下匹配正则表达式仍然是可能的,但我怀疑您使用的正则表达式库是否足够聪明,能够进行优化

通过使数据部分(
((?:.|\\n)*)
)非贪婪:将其更改为
((?:.|\\n)*),您可以修复正则表达式以匹配您希望它匹配的内容
。这也可能解决堆栈爆炸问题,因为它会导致正则表达式在爆炸堆栈之前匹配得更早。但我不知道它是否能正常工作;我真的不知道有关MS实现的任何信息

在我看来,您应该避免反向引用,即使这意味着代码有点复杂。我要做的是首先匹配:

 === ([^=]+) ===\n
然后创建终止字符串:

 "\n=== END " + match[1].str() + " ==="
然后
find()
终止字符串。这意味着您不能再使用正则表达式库的迭代器,这很不幸,但循环仍然非常简单


顺便说一句,我觉得奇怪的是,如果开始分隔符在一行的末尾,那么你只能识别它,如果结束分隔符在一行的开头,那么你就可以识别它。我倾向于要求它们都是完整的行。如果你用我的两步方法用back-reference替换regex,那么实现这一点相对容易。那就是可能被认为是另一个暗示,带back引用的正则表达式并不是真正正确的方法。

[需要引用],[需要引用],[需要引用]和[需要引用]。我还建议使用Boostregex@sehe好吧,看聊天。还有,“在我看来”,虽然肯定是一种逃避,但有点排除了引用的必要。记住,我当时在场。而且,“IMO”并不明确适用于所有索赔。事实上,“但即使不是”似乎明确地消除了该条款对随后索赔的影响。