regex_iterator 和 regex_token_iterator 之间的主要区别是什么?

What is key difference between regex_iterator and regex_token_iterator?

提问人:Damir Tenishev 提问时间:7/29/2023 最后编辑:DailyLearnerDamir Tenishev 更新时间:7/30/2023 访问量:63

问:

查看regex_iteratorregex_token_iterator,我发现主要区别在于:value_type

  • match_results<BidirIt>对于regex_iterator
  • sub_match<BidirIt>为 regex_token_iterator

同时,它们的示例(在这些页面上)显示了相反的行为:

  • regex_iterator在正则表达式中按令牌本身的定义进行拆分
  • regex_token_iterator正则表达式中按分隔符描述拆分

虽然,这在上述文件中没有具体说明。

regex_token_iterator 和 regex_iterator 有什么区别? 指定regex_token_iterator可以有最后一个参数 -1、0 或 1,但我在regex_token_iterator找不到它。这是我错过的一种常识,还是文档错过了这一点?

我的具体问题是是什么让它们如此不同,以至于代码

#include <iostream>
#include <string>
#include <regex>

int main()
{
    std::string input_str = "hi, world";
    const std::regex  reg_ex(R"(\S+\w+|[,.])");

    std::vector<std::string> tokens { 
        std::sregex_token_iterator(input_str.begin(), input_str.end(), reg_ex, 0), 
        std::sregex_token_iterator() 
    };

    for (auto& item : tokens)
    {
        std::cout << item << std::endl;
    }
}

编译和工作没有任何问题,并且基于相同的代码不会编译许多错误消息,这些错误消息隐藏了有关实际问题的信息。实际上,它不能从迭代器中制作。sregex_iteratorvector<string>

请参阅包含该问题的演示

有没有办法以与结果相同的方式处理regex_iterator的结果,并像上面的例子一样直接打包它们?sregex_token_iteratorvector<string>

C++ 正则表达式 C++11 STL

评论

0赞 273K 7/29/2023
嗯,返回对 的引用,这不是std::sregex_token_iterator::operator*()std::sub_match<BidirIt>std::string

答:

3赞 273K 7/29/2023 #1
  1. std::sregex_token_iterator::operator*()返回对 的引用,这不是 。std::sub_match<BidirIt>std::string

  2. 从两个迭代器的初始值设定项列表构造一个向量。调用正确的构造函数需要使用括号。

#include <iostream>
#include <regex>
#include <string>
#include <vector>

int main()
{
    std::string input_str = "hi, world";
    const std::regex  reg_ex(R"(\S+\w+|[,.])");

    std::vector tokens(
        std::sregex_iterator(input_str.begin(), input_str.end(), reg_ex), 
        std::sregex_iterator() 
    );

    for (const auto& item : tokens)
    {
        std::cout << item.str() << std::endl;
    }
}

评论

0赞 Damir Tenishev 7/29/2023
非常感谢!这里有三个额外的问题:(1)切换到括号如何改变这里的游戏?为什么初始值设定项列表适用于sregex_token_iterator而不适用于sregex_iterator?(2)现在这是一个火柴的向量;有没有办法在没有额外转换的情况下即时创建字符串向量?也许是一些就地转换器、包装器等?(3) 对我上面第一个问题中的“最后一个参数 -1、0 或 1”有任何想法;这是文档遗漏还是我的?
1赞 273K 7/29/2023
(1) 如果有一个接受 的构造函数,则它与所有相同类型的参数一起使用。请参阅注释std::initializer_list<T>{...}
1赞 273K 7/29/2023
(2) 你不能这样做 - 它需要一个额外的隐式转换,而没有执行。您可以使用 , ...std::copystd::transform
1赞 273K 7/29/2023
(3) 这是子匹配参数。