8

以下输出“> Hut”,我希望它输出“Hut”。我知道 .* 是贪婪的,但 > 必须匹配并且它在捕获组之外,那么为什么它在我的子匹配中?

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

using namespace std;

int main() {
        regex my_r(".*>(.*)");
        string temp(R"~(cols="64">Hut)~");
        smatch m;
        if (regex_match(temp, m, my_r)) {
                cout << m[1] << endl;
        }
}
4

2 回答 2

7

这是 libstdc++ 实现中的一个错误。观看这些:

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

int main() {
    {
        using namespace std;
        regex my_r("(.*)(6)(.*)");
        smatch m;
        if (regex_match(std::string{"123456789"}, m, my_r)) {
            std::cout << m.length(1) << ", "
                      << m.length(2) << ", "
                      << m.length(3) << std::endl;
        }
    }

    {
        using namespace boost;
        regex my_r("(.*)(6)(.*)");
        smatch m;
        if (regex_match(std::string{"123456789"}, m, my_r)) {
            std::cout << m.length(1) << ", "
                      << m.length(2) << ", "
                      << m.length(3) << std::endl;

        }
    }

    return 0;
}

如果使用 gcc 编译,第一个(libstdc++)返回完全错误的结果9、-2、4,第二个(boost 的实现)按预期返回5、1、3 。

如果您使用 clang + libc++ 编译,您的代码可以正常工作。

(请注意,libstdc++ 的正则表达式实现仅“部分支持”,如http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52719中所述。)

于 2012-06-05T08:07:20.243 回答
3

您可以修改正则表达式,以便将匹配的部分分成组:

std::regex my_r("(.*)>(.*)\\).*"); // group1>group2).*
std::string temp("~(cols=\"64\">Hut)~");
std::sregex_iterator reg_it(temp.begin(), temp.end(), my_r);

if (reg_it->size() > 1) {
    std::cout
        << "1: " << reg_it->str(1) << std::endl  // group1 match
        << "2: " << reg_it->str(2) << std::endl; // group2 match
}

输出:

1: ~(cols="64"
2: Hut

请注意,组是由大括号指定的( /* your regex here */ ),如果您想将大括号作为表达式的一部分,那么您需要使用代码中的 来对其进行\转义\\。有关详细信息,请参阅分组构造

这个问题也可以帮助你:我如何遍历来自 std::regex_search 的结果?

也不要using namespace std;在文件的开头使用,这是一种不好的做法。

于 2012-06-05T08:16:58.583 回答