基本上,我想做的是在单个字符串上运行多个(15-25)正则表达式替换,并实现最佳的内存管理。
概述:
通过ftp流式传输仅为文本的文件(有时为html),将其附加到 StringBuilder
以获取非常大的字符串。文件大小范围从300KB到30MB。
正则表达式有一定复杂性,但需要文件的多行(例如标识书的部分),因此任意地断开字符串或在每个下载循环中运行替换都不可行。
一个样例替换:
Regex re = new Regex("<A.*?>Table of Contents</A>", RegexOptions.IgnoreCase);
source = re.Replace(source, "");
每次替换运行时,内存都会飙升,我知道这是因为在C#中,字符串是不可变的,所以需要进行复制——即使我调用
GC.Collect()
也无法帮助减少30MB文件的内存消耗。有没有更好的方法来处理这个问题,或者有没有一种使用恒定内存执行多个正则表达式替换的方法(制作2份副本(因此在内存中占用60MB),执行搜索,丢弃副本并返回到30MB)?
更新:
看起来没有简单的答案,但是对于未来遇到这个问题的人们,我最终结合了以下所有答案才将其达到可接受的状态:
如果可能,将字符串拆分成块,请参见manojlds的答案,以便在读取文件时寻找适当的结束点。
如果无法拆分,则至少稍后拆分——请参见ChrisWue的答案,以获取一些可以帮助该过程的外部工具,以管道传输到文件。
优化正则表达式,避免贪婪操作符,并尽可能限制引擎必须执行的操作量——请参见Sylverdrag的答案。
尽可能组合正则表达式,这可以减少替换的数量,特别是在正则表达式不基于彼此时非常有用(在清理错误输入方面非常有用)——请参见Brian Reichle的答案获取代码示例。