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

Replace starting comment in Java source file

我正在编写一个 c# 程序来更新 java 源代码的起始注释 - 这通常是许可证 header-。以下代码段可以完成这项工作。

                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

这不是垃圾 Collection 的问题,因为强制它不能解决问题。 RegexOptions.Compiled 与否并不重要。

我很确定这取决于模式中的一个问题,因为挂起出现在某些文件上 - 如果从处理中删除 - 让作业继续直到一千个源文件结束。但是如果我单独处理这些文件,它可以工作,如果我使用在线测试工具作为 http://regexstorm.net/tester https://www.myregextester.com/index.php

如果有任何方法可以更好地优化用于查找文件中第一个 Java 评论的搜索模式,请告诉我。

提前致谢。

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

常用的技术是 unroll/unwrap 带有否定字符 class 和量化组的结构。

您可以使用

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

regex demo

正则表达式细分:

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