我正在编写一个c#程序来更新起始注释 - 通常是java源代码的许可标题。以下代码片段完成了这项工作。
foreach (string r in allfiles)
{
// GC.Collect();
string thefile = System.IO.File.ReadAllText(r);
var pattern = @"/\*(?s:.*?)\*/[\s\S]*?package";
Regex regex1 = new Regex(pattern /*,RegexOptions.Compiled */) ;
var replaced = regex1.Replace(thefile, newheader + "package");
System.IO.File.WriteAllText(r, replaced);
}
问题是,经过数百个源文件处理后,进程挂起在.Replace
这不是垃圾收集的问题,因为强迫它无法解决问题。 如果RegexOptions.Compiled与否则无关紧要。
我很确定它取决于模式中的问题,因为挂起出现在某些文件上 - 如果从处理中移除 - 让作业继续直到1000个源文件结束。但是,如果我单独处理这些文件,如果我使用在线测试工具,它也可以工作 http://regexstorm.net/tester https://www.myregextester.com/index.php
如果有任何方法可以更好地优化搜索模式以查找文件中的第一个Java评论,请告诉我。
提前谢谢。
答案 0 :(得分:0)
您的正则表达式包含2个与延迟点匹配相关的瓶颈(单线模式下为.
,[\s\S]*?
为同义词)。在针对大文件运行正则表达式时,回溯缓冲区可能会轻松快速地溢出。
常用技术是使用否定字符类和量化组展开/解包构造。
您可以使用
@"/\*[^*]*(?:\*(?!/)[^*]*)*\*/\s*package"
请参阅regex demo
正则表达式分解:
/\*
- 文字/*
[^*]*
- 除*
(?:\*(?!/)[^*]*)*
- (?s:.*?)
的展开变体,匹配0个或多个序列...
\*(?!/)
- *
符号后面没有/
[^*]*
- 除*
\*/
- */
\s*
- 0个或更多空格字符package
- 文字字母序列package