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迭代器