【问题标题】:Search (big) file via regex in C++在 C++ 中通过正则表达式搜索(大)文件
【发布时间】:2017-01-17 19:34:02
【问题描述】:

我正在大量文件中搜索大量字符串,但有些文件太大而无法放入内存。我尝试加载 10kB 左右的块并且它起作用了,但是如果我正在寻找的字符串已经被分割了 - 它的一半在这个块中,另一半在另一个?我的模式永远不会匹配。有没有办法解决这个问题?

【问题讨论】:

  • 每次多加载一个chunk,这样你在chunk N和N+1中搜索,然后是N+1和N+2ː)
  • 问题标记为 C++,但也许你可以使用像 grep 这样的命令行工具?
  • @Geoffroy 如此简单有效 - 谢谢!如果可以,请写下您的评论作为答案,以便我批准。
  • 如果你加载块 NN + 1,但你的匹配跨越块 N N + 1N + 2,你不会找到它。您只是降低了代码中断的可能性。不过它还是坏了。
  • 只有在您可以提前确定所有匹配项的上限时才有可能。通常情况并非如此。如果您的正则表达式中有*,则匹配可以是任意长度。

标签: c++ regex search split


【解决方案1】:

如果用 C++ 编写解决方案不是硬性约束,请尝试 find 和 grep

find . -type f -name "*.txt" -size +4096k -exec grep "whale" {} +
  • 输入只搜索文件
  • 名称仅以扩展名 txt 结尾的文件
  • 大小仅限大于 4096kb 的文件
  • 将“whale”替换为所需的正则表达式。

【讨论】:

    【解决方案2】:

    不要只在块上运行你的正则表达式。你没有说你正在使用哪个库,但你想要一个可以将数据流式传输到的库。标准 C++11 正则表达式库显然需要C++ regular expression over a stream 中提到的双向迭代器

    然而libsregex 声称提供了一个非回溯实现,并且有一个 API,您可以调用每个块,保持前一个块的状态,允许跨越多个块的匹配。

    【讨论】:

      【解决方案3】:

      不可移植,但将文件加载为内存映射文件。 C++ 正则表达式的目标序列 可以是迭代器对,因此您无需将该文件复制到std::string。因此,您无需一次将整个文件加载到 RAM 中。

      当然,如果您的输入非常糟糕,回溯可能会很糟糕,但这几乎是不可避免的。如果您的模式是 ab*c 并且您有 4GB 的 b 后跟 d,那么是的,您必须一直回溯到第一个 a。而且您的正则表达式实现可能不够聪明,无法注意到b* 不包含a

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-30
        • 1970-01-01
        • 2020-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多