vc ++ std :: regex_match返回带有替换正则表达式的额外空字符串

时间:2016-07-29 11:39:30

标签: c++ regex

为什么这个正则表达式返回一个空字符串与std :: regex_match的额外匹配?

std::regex trim_comments_spaces("^\\s*(?:(?:(.*?)\\s*[/]{2,}.*)|(?:(.*?)\\s*))$");

它似乎给出了正确的匹配,但我必须访问std :: smatch结果的第三个元素。,这让我怀疑我的修改/分组/捕获语法有些错误。

std::string trim_line(std::string current_line) {

    std::string trimmed_line = "";

    if (current_line != "#include <glsl.h>") {

        std::regex trim_comments_spaces("^\\s*(?:(?:(.*?)\\s*[/]{2,}.*)|(?:(.*?)\\s*))$");
        std::smatch sub_matches;

        if (std::regex_match(current_line, sub_matches, trim_comments_spaces)) {
            std::cout << sub_matches.size() << "\n";
            std::string sub_string = sub_matches[2].str();

            if (sub_string != "") {
                std::regex validate_line("^(?:(?:[a-z][a-zA-Z0-9\\s_+*\\-/=><&|^?:{().,[\\]]*[;{})])|[}])$");

                if (std::regex_match(sub_string.begin(), sub_string.end(), validate_line)) {
                    trimmed_line = sub_string;
                }
                else {
                    std::cout << "Syntax error(2): " << sub_string << "\n";
                }           
            }
        }
        else {
            std::cout << "Syntax error(1): " << current_line << "\n";
        }
    }

    return trimmed_line;
}

1 个答案:

答案 0 :(得分:1)

你的正则表达式,一旦针对匹配的字符串执行,将获取一个有3个组的smatch对象:

  • 1)第0组 - 整场比赛,
  • 2)第一组 - (.*?)
  • 中的^\\s*(?:(?:(.*?)\\s*[/]{2,}.*)|
  • 3)第2组 - (.*?)
  • 中的(?:(.*?)\\s*))$

如果一个组匹配,如果你在模式中定义了(...),它将首先用空字符串初始化,然后,它将填充捕获的值,或者它将保持为空。当然,除非您使用具有相同名称的组或分支重置,否则您无法在std::regex中访问它们。您可以使用提升并使用"^\\s*(?|(?:(.*?)\\s*[/]{2,}.*)|(?:(.*?)\\s*))$"(请参阅(?|构造,然后您所需的所有值都将在第1组中)

如果您使用当前代码,则可以连接第1组和第2组,因为其中一个将始终为空。

std::string sub_string = sub_matches[1].str() + sub_matches[2].str();

请参阅C++ demo