C++ 流上的正则表达式

11

我有一个非常大的文本文件(多达几百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';
    }  
}

1
“我能使用流迭代器吗?” 简单的回答是:不行。正则表达式匹配需要双向迭代器。这并不是任意的限制。你最好找到一个类,通过内部缓存将流迭代器适配为双向迭代器。然而,标准库并没有提供这个功能。即使是istreambuf_iterator也只是一个输入迭代器。 - Konrad Rudolph
如果您发布一些示例代码,即使它实际上不起作用,也会很有帮助。我的意思是,只需一个带有几行代码的main函数,例如尝试使用std::istream_iterator。这将有助于确保其他人正确理解您的问题。 - hyde
为什么我们需要迭代输入?std::regex_match的匹配结果已经是一个序列了。 - 9dan
1
我认为0.2GB的字符串在今天并不是很大的尺寸。如果它无法适应地址空间(超过2GB?),就会出现真正的问题。 - 9dan
7
如果不必要,将200MB数据加载到内存中是很多的。我真的希望程序不要只因为“人们有大量RAM”而这样做! - Lightness Races in Orbit
显示剩余6条评论
1个回答

1

你不能在流上进行匹配,因为失败的匹配意味着什么?正则表达式的开头是否已经匹配,并且需要更多字符进行流式处理,还是没有任何部分匹配流。

但是在编辑后,我们可以在字符串上找到匹配项的偏移量和范围。您可以使用以下方法:

const vector<smatch> foo = { sregex_iterator(cbegin(s), cend(s), find_jumping_fox), sregex_iterator() }

这里有详细的解释:https://topanswers.xyz/cplusplus?q=729#a845

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接