1

当在运行时确定匹配参数的数量时,我无法使用 RE2::FullMatchN。

const RE2::Arg* args[10];
int n;
bool match = RE2::FullMatchN("abcd@abcd.com", "([^ @]+)@([^ @]+)", args, n);

最后,我想在上面的例子中获得 2 个字符串 - abcd 和 abcd.com

4

1 回答 1

9

您可以RE2用作对象。如果RE2对象已成功解析正则表达式,您可以调用NumberOfCapturingGroups()方法。知道有多少个捕获组,您可以动态分配一个指针数组RE2::Arg

这是一个示例函数:

我还建议您将正则表达式包装在 '(' - ')' 中,因为re2它不会0th像许多其他 API 那样默认返回完全匹配的参数。

bool re2_full_match(const std::string & pattern, const std::string & str, std::vector<std::string> & results)
{
    std::string wrapped_pattern = "(" + pattern + ")";
    RE2::Options opt;
    opt.set_log_errors(false);
    opt.set_case_sensitive(false);
    opt.set_utf8(false);
    RE2 re2(wrapped_pattern, opt);
    if (!re2.ok()) {
        /// Failed to compile regular expression.
        return false;
    }

    /// Argument vector.
    std::vector<RE2::Arg> arguments;
    /// Vercor of pointers to arguments.
    std::vector<RE2::Arg *> arguments_ptrs;

    /// Get number of arguments.
    std::size_t args_count = re2.NumberOfCapturingGroups();

    /// Adjust vectors sizes.
    arguments.resize(args_count);
    arguments_ptrs.resize(args_count);
    results.resize(args_count);
    /// Capture pointers to stack objects and result object in vector..
    for (std::size_t i = 0; i < args_count; ++i) {
        /// Bind argument to string from vector.
        arguments[i] = &results[i];
        /// Save pointer to argument.
        arguments_ptrs[i] = &arguments[i];
    }

    return RE2::FullMatchN(StringPiece(str), re2, arguments_ptrs.data(), args_count);
}

但本着正则表达式的精神,我建议您使用^....$而不是full_match,并重命名full_matchfind

bool re2_find(const std::string & pattern, const std::string & str, std::vector<std::string> & results)
{
    std::string wrapped_pattern = "(" + pattern + ")";
    RE2::Options opt;
    opt.set_log_errors(false);
    opt.set_case_sensitive(false);
    opt.set_utf8(false);
    RE2 re2(wrapped_pattern, opt);
    if (!re2.ok()) {
        /// Failed to compile regular expression.
        return false;
    }

    /// Argument vector.
    std::vector<RE2::Arg> arguments;
    /// Vercor of pointers to arguments.
    std::vector<RE2::Arg *> arguments_ptrs;

    /// Get number of arguments.
    std::size_t args_count = re2.NumberOfCapturingGroups();

    /// Adjust vectors sizes.
    arguments.resize(args_count);
    arguments_ptrs.resize(args_count);
    results.resize(args_count);
    /// Capture pointers to stack objects and result object in vector..
    for (std::size_t i = 0; i < args_count; ++i) {
        /// Bind argument to string from vector.
        arguments[i] = &results[i];
        /// Save pointer to argument.
        arguments_ptrs[i] = &arguments[i];
    }

    StringPiece piece(str);
    return RE2::FindAndConsumeN(&piece, re2, arguments_ptrs.data(), args_count);
}
于 2014-09-17T12:14:40.263 回答