C++ 正则表达式 : non-greedy match

标签 c++ regex c++11 c++14 regex-greedy

我目前正在尝试制作一个匹配 URL 参数并提取它们的正则表达式。

例如,如果我得到以下参数字符串?param1=someValue¶m2=someOtherValuestd::regex_match应该提取以下内容:

  • param1
  • some_content
  • param2
  • some_other_content

在尝试了不同的正则表达式模式之后,我终于构建了一个与我想要的相对应的模式:std::regex("(?:[\\?&]([^=&]+)=([^= &]+))*").

如果我采用前面的示例,std::regex_match 将按预期进行匹配。但是,它不会提取预期值,只保留最后捕获的值。

例如下面的代码:

std::regex paramsRegex("(?:[\\?&]([^=&]+)=([^=&]+))*");
std::string arg = "?param1=someValue&param2=someOtherValue";
std::smatch sm;

std::regex_match(arg, sm, paramsRegex);
for (const auto &match : sm)
   std::cout << match << std::endl;

将给出以下输出:

param2
someOtherValue

如您所见,param1 及其值被跳过且未被捕获。

在谷歌上搜索后,我发现这是由于贪婪捕获造成的,我将我的正则表达式修改为 "(?:[\\?&]([^=&]+)=([ ^=&]+))\\*?" 以启用非贪婪捕获。

当我在 rubular 上尝试时,这个正则表达式运行良好但是当我在 C++ 中使用它时它不匹配(std::regex_match 返回 false 并且没有捕获任何内容)。

我尝试了不同的 std::regex_constants 选项(使用 std::regex_constants::grep 的不同正则表达式语法,std::regex_constants::egrep, ...) 但结果是一样的。

有人知道如何在 C++ 中进行非贪婪正则表达式捕获吗?

最佳答案

作为Casimir et Hippolyte在他的 comment 中解释,我只需要:

  • 去掉量词
  • 使用std::regex_iterator

它给了我以下代码:

std::regex paramsRegex("[\\?&]([^=]+)=([^&]+)");
std::string url_params = "?key1=val1&key2=val2&key3=val3&key4=val4";
std::smatch sm;

auto params_it = std::sregex_iterator(url_params.cbegin(), url_params.cend(), paramsRegex);
auto params_end = std::sregex_iterator();

while (params_it != params_end) {
    auto param = params_it->str();

    std::regex_match(param, sm, paramsRegex);
    for (const auto &s : sm)
       std::cout << s << std::endl;

    ++params_it;
}

这是输出:

?key1=val1
key1
val1
&key2=val2
key2
val2
&key3=val3
key3
val3
&key4=val4
key4
val4

原来的正则表达式 (?:[\\?&]([^=&]+)=([^=&]+))* 只是变成了 [\\?&]([^=]+)=([^&]+).

然后,通过使用 std::sregex_iterator,我在每个匹配组(?key1=val1, &key2=val2 , ...).

最后,通过在每个子字符串上调用 std::regex_match,我可以检索参数值。

关于C++ 正则表达式 : non-greedy match,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30007942/

相关文章:

c++ - 如何阅读 MSVC C++ 链接错误

c++ - 转换和验证字符串

c++ - 结构化输出

c++ - 将 8 个位置的 int 数组转换为 char

c++ - Windows 事件查看器锁定了我的 EXE 文件

c++ - 继承类问题

javascript - 正则表达式 : match everything beginning from second dot including dot

java - 使用正则表达式替换两个符号之间的文本

java - 当且仅当前后字符不是 'dot' 时,如何在 'dot' 上拆分字符串

c++ - Lambda 变量捕获