用C ++收集模式元素

时间:2013-01-23 08:49:40

标签: c++ regex c++11 iterator pattern-matching

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

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

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

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

在分析该模式时,我想收集其中的“变量”,即以冒号开头和结尾的子串。以下代码段(改编自Split a string using 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,而不是匹配本身)会是什么?我可以手动迭代regexp匹配并在循环中累积匹配,但我怀疑可能有更优雅的类似于{first, last}表达式。

假设我的背景清楚,任何考虑到它的评论也是受欢迎的:

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

1 个答案:

答案 0 :(得分:1)

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

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

1表示“我对匹配第一子表达式感兴趣”。默认值0表示“我对匹配感兴趣”,-1表示“我对匹配之间的文字感兴趣”。

(其他评论仍然欢迎)。