WSk*_*kid 8 c# regex string memory-management
基本上我想要做的是运行多个什么(15-25)正则表达式替换上一个字符串尽可能最好的内存管理.
概述:通过ftp附加到StringBuilder一个非常大的字符串来传输一个纯文本文件(有时是html).文件大小范围从300KB到30MB.
正则表达式是半复杂的,但需要文件的多行(例如,识别书的部分),因此任意破坏字符串,或者在每个下载循环上运行替换都是不可能的.
替换样本:
Regex re = new Regex("<A.*?>Table of Contents</A>", RegexOptions.IgnoreCase);
source = re.Replace(source, "");
Run Code Online (Sandbox Code Playgroud)
每次运行更换内存天空火箭,我知道这是因为字符串在C#中是不可变的,它需要复制 - 即使我称GC.Collect()它仍然对30MB文件没有帮助.
有关更好的方法的建议,或使用常量内存执行多个正则表达式的方法替换(制作2个副本(内存为60MB),执行搜索,丢弃复制回30MB)?
似乎没有一个简单的答案,但对于未来的人来说,我最终使用下面所有答案的组合使其达到可接受的状态:
如果可能的话,将字符串拆分成块,请参阅manojlds的答案,以便在读取文件时找到合适的终点.
如果你不能像流一样进行拆分,至少可以在以后拆分 - 请参阅ChrisWue的一些外部工具的答案,这些工具可能有助于这个流程管道到文件.
优化正则表达式,避免贪婪的运算符,并尽可能地限制引擎必须做的事情 - 请参阅Sylverdrag的回答.
尽可能结合正则表达式,这减少了正则表达式不相互依赖时的替换次数(在这种情况下用于清除错误输入) - 请参阅Brian Reichle对代码示例的回答.
谢谢你们!
根据正则表达式的性质,您也许能够将它们组合成一个正则表达式,并使用接收 MatchEvaluator 委托的 Replace() 重载来确定匹配字符串的替换。
Regex re = new Regex("First Pattern|Second Pattern|Super(Mega)*Delux", RegexOptions.IgnoreCase);
source = re.Replace(source, delegate(Match m)
{
string value = m.Value;
if(value.Equals("first pattern", StringComparison.OrdinalIgnoreCase)
{
return "1st";
}
else if(value.Equals("second pattern", StringComparison.OrdinalIgnoreCase)
{
return "2nd";
}
else
{
return "";
}
});
Run Code Online (Sandbox Code Playgroud)
当然,如果后面的模式需要能够匹配早期替换的结果,那么这就不行了。
| 归档时间: |
|
| 查看次数: |
2761 次 |
| 最近记录: |