在整个文件中进行多行正则表达式搜索
我已经找到大量示例来使用正则表达式替换文件中的文本。 然而,这一切归结为两个版本:
1.迭代文件中的所有行并将regex应用于每一行
2.加载整个文件。
第2号使用“我的”文件是不可行的 – 它们大概是2GiB ……
至于第1名:目前这是我的方法,但我想知道……如果需要应用跨越多行的正则表达式怎么办?
这是答案:
没有简单的方法
我找到了一个StreamRegex-Class ,可以做我想要的。
从我能掌握的算法:
- 使用空缓冲区从文件的开头开始
- 做(
- 将一大块文件添加到缓冲区
- 如果缓冲区中有匹配项
- 标记比赛
- 从缓冲区中删除匹配结束前出现的所有数据
- )虽然还有一些文件遗留下来
这样,加载完整文件并不是必需的 – 或者至少减少了在内存中加载完整文件的机会……
但是:最坏的情况是整个文件中没有匹配项 – 在这种情况下,完整文件将被加载到内存中。
正则表达式不是一种可行的方式,特别是没有这些大量的文本。 创建一个自己的小解析器:
- 逐行读取文件;
- 对于每一行:
- 循环遍历字符char by char跟踪任何打开/关闭字符串文字
- 当你遇到’/ *’(并且你不是’在’字符串’里面)时,存储该偏移数字并循环直到遇到第一个’* /’并存储该数字
这将为您提供注释块的所有起始和结束偏移数。 您现在应该能够通过创建临时文件并将原始文件中的文本写入临时文件来替换它们(如果您当然在注释块中,则可以编写其他内容)。
编辑:2GiB的源文件??
也许您可以一次加载2行(或更多,取决于您认为匹配将跨越多少行),并重叠它们,例如:加载行1-2,然后下一个循环加载行2-3 ,下次加载3-4; 并在每个循环中组合两行的多行正则表达式。
我会说你应该在进行替换之前对数据进行预解析/规范化,以便每行描述一个可能需要替换的数据集。 否则,您会遇到数据完整性的复杂问题,如果没有其他许多困难,这些问题无法真正解决。
如果有办法将数据块化为逻辑块,那么您可以构建一个使用mapreduce模式来解析数据的程序。
我和巴特在一起; 你真的应该使用某种解析器。
或者,如果你不介意产生子进程,你可以只使用sed ( 在windows上有一个本机端口 ,或者你可以使用Cygwin )
如果你不介意让你的手变得有点脏(你的正则表达式很简单,或者你对速度有强烈的渴望并且不介意受苦),你可以使用Ragel 。 它可以针对C#,尽管该网站没有提到它。 您需要在64位进程中包装FileStream以提供缓冲索引器或使用内存映射文件(使用不安全指针)来将其用于大文件。