收集C++中的图案元素

collecting pattern elements in C++

本文关键字:元素 C++ 收集      更新时间:2023-10-16

我需要从字符串中收集与某种模式匹配的元素。例如,让我们有以下 URI 片段:

std::string uri = "/api/customer/123/order/456/total";

这应该与以下模式相匹配:

std::string pattern = "/api/customer/:customerNum:/order/:orderNum:/total";

在分析该模式时,我想收集其中的"变量",即以冒号开头和结尾的子字符串。以下代码片段(改编自使用 C++11 拆分字符串)几乎可以完成这项工作:

std::set<std::string> patternVariables(const std::string &uriPattern)
{
    std::regex re(":([^:]+):");            // find a word surrounded by ":"
    std::sregex_token_iterator
    first ( uriPattern.begin(), uriPattern.end(), re),
    last;
    std::set<std::string> comp = {first, last};
    return comp;
}

该代码段的问题在于它收集了包括":"标记在内的变量。收集没有冒号的变量(即匹配中的1,而不是匹配本身)的惯用方法是什么?我可以手动迭代正则表达式匹配项并在循环中累积匹配项,但我怀疑可能有类似于{first, last}表达式的更优雅的东西。

假设我的上下文很清楚,也欢迎任何考虑到它的评论:

  • 在我的模式中标记变量的更好约定
  • 关于更好的正则表达式的建议
  • 对工作流下一步的前瞻性思考:将模式与实际 URI 匹配,返回变量及其值的映射(包括同一变量可能多次出现的模式)。

也许我应该完全删除我的问题。班级regex_token_iterator已经预料到了这种需求。这个想法是在其构造函数中使用可选的第 4 个参数,因此:

std::sregex_token_iterator
first ( uriPattern.begin(), uriPattern.end(), re, 1),
last;

1的意思是"我对匹配的第一个子表达式感兴趣"。默认值 0 表示"我对匹配项感兴趣",-1 表示"我对匹配项之间的文本感兴趣"。

(其他评论仍然欢迎)。