替换Java源文件中的起始注释

时间:2015-11-09 14:16:49

标签: java c# .net regex string

我正在编写一个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评论,请告诉我。

提前谢谢。

1 个答案:

答案 0 :(得分:0)

您的正则表达式包含2个与延迟点匹配相关的瓶颈(单线模式下为.[\s\S]*?为同义词)。在针对大文件运行正则表达式时,回溯缓冲区可能会轻松快速地溢出。

常用技术是使用否定字符类和量化组展开/解包构造。

您可以使用

@"/\*[^*]*(?:\*(?!/)[^*]*)*\*/\s*package"

请参阅regex demo

正则表达式分解:

  • /\* - 文字/*
  • [^*]* - 除*
  • 以外的0个或多个字符
  • (?:\*(?!/)[^*]*)* - (?s:.*?)的展开变体,匹配0个或多个序列...
    • \*(?!/) - *符号后面没有/
    • [^*]* - 除*
    • 以外的0个或多个符号
  • \*/ - */
  • 的文字序列
  • \s* - 0个或更多空格字符
  • package - 文字字母序列package