【发布时间】:2016-01-21 22:05:55
【问题描述】:
我有一个非常大的文本文件(最多几百 MB),我想用 STL 正则表达式处理它。我正在寻找的匹配区域跨越几行,并且在文件中至少出现了几千次。
我可以为此目的使用流迭代器吗?我试过std::istream_iterator<char>,但没有运气。有人可以发布一个最小的工作示例吗?
请注意,我正在寻找仅涉及 STL 的解决方案。在完美的解决方案中,我想遍历所有匹配项。
编辑
阅读评论后,我明白这是不可能的。因此,也许还有另一种方法可以迭代在大文本文件中找到的正则表达式匹配:
#include <regex>
#include <iostream>
#include <string>
const std::string s = R"(Quick brown fox
jumps over
several lines)"; // At least 200MB of multiline text here
int main(int argc,char* argv[]) {
std::regex find_jumping_fox("(Quick(?:.|\\n)+?jump\\S*?)");
auto it = std::sregex_iterator(s.begin(), s.end(), find_jumping_fox);
for (std::sregex_iterator i = it; i != std::sregex_iterator(); ++i) {
std::smatch match = *i;
std::string match_str = match.str();
std::cout << match_str << '\n';
}
}
【问题讨论】:
-
“我可以使用流迭代器吗”——简单的回答:不。正则表达式匹配需要双向迭代器。这也不是一个任意的限制。最好的办法是找到一个通过内部缓存将流迭代器适配为双向迭代器的类。但是,标准库不提供此功能。甚至
istreambuf_iterator也只是一个输入迭代器。 -
如果您发布示例代码会有所帮助,即使它实际上并没有工作。我的意思是,只是一个带有几行代码的
main函数,例如尝试使用std::istream_iterator。这将有助于确保其他人正确理解您的问题。 -
为什么我们需要遍历输入?
std::regex_match的匹配结果已经是一个序列了。 -
我认为现在 0.2GB 的字符串并不是那么大。如果地址空间无法容纳(超过 2GB?),就会出现真正的问题。
-
@9dan:如果您实际上不需要,200MB 是要加载到内存中的大量数据。我真的希望程序停止这样做只是因为“人们有很多 RAM”!