不同平台下C++正则表达式的差异

4
我有以下代码:
#include <string>
#include <regex>
#include <iostream>

int main()
{
        std::string s;
        s += '\x06';
        s += '\x00';

        std::regex r(std::string(1, '\x06') + '\x00');
        std::smatch sm;
        if (std::regex_search(s, sm, r))
        {
                std::cout << "Success\n";
                return 0;
        }

        std::cout << "Failure\n";
}

在Windows上,我得到了“Success”而在Linux上,我得到了“Failure”。我在Windows使用MSVC 19.28,在Linux上使用GNU 9.3.0。为什么输出不同?

我怀疑零字符会干扰,如果你用\x01替换\x00会怎样?如果有帮助的话,我会说这可能是MSVC的错误或C++标准的错误。 - yeputons
1
@Eljay,在 Linux 上,我使用 clang 10.0.0 仍然收到“失败”的消息。 - user680891
1
@user680891 这不是clang,而是libc++与libstdc++之间的区别:https://godbolt.org/z/o4xcT6E67 - Alan Birtles
2
如果我在正则表达式中用“\0”替换“\x00”,它就可以在gcc中工作。(即,正则表达式包含反斜杠后跟数字0,而不是值为零的字节)。 - Kevin
显示剩余3条评论
1个回答

0
根据C++ ECMAScript regex flavor reference
引用块中指出:十进制转义符\0不是反向引用,它是表示null字符的字符转义符。不能在其后跟随十进制数字。
因此,要匹配Null字符,需要使用\0 文本字符串、一个字面意义上的\字符和一个0字符。可以使用正则字符串文字表示为"\\0"或更好地使用原始字符串文字表示为R"(\0)"
以下打印 "Success":
#include <string>
#include <regex>
#include <iostream>

int main()
{
        std::string s;
        s += '\x06';
        s += '\x00';
        std::regex r(std::string(1, '\x06') + R"(\0)");
        std::smatch sm;
        if (std::regex_search(s, sm, r))
        {
                std::cout << "Success\n";
                return 0;
        }

        std::cout << "Failure\n";
}

ECMAScript正则表达式引擎是否明确地不支持在正则表达式中直接使用空字符?我在那个页面上没有看到任何相关说明。 - Kevin
1
你可以在std::string中有一个空字符,就像OP所做的那样,你也可以从std::string创建一个std::regex。因此,std::regex对象可以包含一个空字符。它是否实际支持或应该支持是个问题。 - Kevin
构造一个字符串,该字符串由指向s的字符字符串的前count个字符组成。s可以包含空字符。字符串的长度为count。如果[s,s + count)不是有效范围,则行为未定义。请参见https://en.cppreference.com/w/cpp/string/basic_string/basic_string。 - Kevin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接