Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在istream上使用regex_迭代器_C++_Regex_Iterator_Istream_Istream Iterator - Fatal编程技术网

C++ 在istream上使用regex_迭代器

C++ 在istream上使用regex_迭代器,c++,regex,iterator,istream,istream-iterator,C++,Regex,Iterator,Istream,Istream Iterator,我希望能够解决这样的问题:istream需要用复杂的分隔符标记;使istream标记化的唯一方法是: 在istream中一次读取一个字符 收集字符 命中分隔符时,将集合作为标记返回 正则表达式非常擅长使用复杂分隔符标记字符串: string foo{ "A\nB\rC\n\r" }; vector<string> bar; // This puts {"A", "B", "C"} into bar transform(sregex_iterator(foo.cbegin(), fo

我希望能够解决这样的问题:
istream
需要用复杂的分隔符标记;使
istream
标记化的唯一方法是:

  • istream
    中一次读取一个字符
  • 收集字符
  • 命中分隔符时,将集合作为标记返回
  • 正则表达式非常擅长使用复杂分隔符标记字符串:

    string foo{ "A\nB\rC\n\r" };
    vector<string> bar;
    
    // This puts {"A", "B", "C"} into bar
    transform(sregex_iterator(foo.cbegin(), foo.cend(), regex("(.*)(?:\n\r?|\r)")), sregex_iterator(), back_inserter(bar), [](const smatch& i){ return i[1].str(); });
    
    string foo{“A\nB\rC\n\r”};
    矢量条;
    //这会将{“A”,“B”,“C”}放入条中
    转换(sregex_迭代器(foo.cbegin(),foo.cend(),regex((*)(?:\n\r?|\r)”),sregex_迭代器(),back_插入器(bar),[](const smatch&i){return i[1].str()});
    
    但是我不能在
    istream
    上使用
    regex\u迭代器(我的解决方案是先对
    istream
    发出声音,然后在其上运行
    regex\u迭代器,但是发出声音的步骤似乎是多余的)


    是否存在
    istream\u iterator
    regex\u iterator
    的邪恶组合,或者如果我想要它,我必须自己写吗?

    我认为不是。
    istream\u iterator
    input\u iterator\u标签
    regex\u iterator
    希望使用双向迭代进行初始化迭代器(
    双向迭代器\u标记


    如果您的分隔符regex足够复杂,以至于您自己无法读取流,那么最好的方法就是真正地读入
    istream

    这个问题是关于代码外观的:

  • 因为我们知道一个
    regex
    一次可以处理1个字符,所以这个问题要求使用库一次解析
    istream
    1个字符,而不是在内部一次读取和解析
    istream
    1个字符
  • 由于每次解析一个
    istream
    1个字符仍会将该字符复制到临时变量(缓冲区)中,因此此代码试图避免在内部缓冲所有代码,这取决于库而不是抽象该字符

  • C++11的
    regex
    es使用ECMA-262,它不支持look aheads或look behinds:这意味着
    regex
    只能使用
    输入迭代器标签进行匹配,但在C++11中实现的显然不支持

    另一方面,
    boost::regex_迭代器
    确实支持
    boost::match_partial
    标志(即,
    boost::match_partial
    允许用户在输入结束时不匹配文件的一部分并运行
    regex
    在正则表达式中的该位置,等待更多的数据被添加到缓冲区。您可以在这里看到一个示例:在一般情况下,如
    “A\nB\rC\n\r”
    ,这可以节省缓冲区大小

    boost::match_partial
    有4个缺点:

  • 在最坏的情况下,如
    “ABC\n”
    这样用户就不会节省任何空间,他必须发出整个
    istream
  • 如果程序员可以猜测缓冲区大小过大,即它包含分隔符和大量其他内容,那么减少缓冲区大小的好处就白白浪费了
  • 当选择的缓冲区大小太小时,与整个文件的slurping相比,将需要额外的计算,因此此方法在分隔符密集的字符串中表现出色
  • 包含
    boost
    总是会导致膨胀
  • 回过头来回答这个问题:标准库
    regex\u迭代器
    无法对
    input\u迭代器标签
    进行操作,需要对整个
    istream
    进行slurping。一个
    boost::regex\u迭代器
    允许用户可能比整个
    istream
    的slurping更少。因为这是一个关于代码应用程序的问题尽管如此,而且由于
    boost::regex\u迭代器的最坏情况无论如何都需要对整个文件进行slurp处理,所以这并不是对这个问题的好答案

    为了获得最佳的代码外观,最好的选择是在整个文件上运行标准的
    regex\u迭代器