You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java正则表达式匹配.java文件错误文本的原因排查

Java正则表达式错误匹配大块非版权内容,求排查思路

完全披露:本人仍为Java新手。

我正在参与一个开源项目,团队决定移除所有文件里的版权头注释,统一用项目根目录的LICENSE.txt文件替代。因为我的IDE没法跨文件批量识别正则模式,所以写了个Java脚本处理这件事——下面是更新后的可用版本(不会操作隐藏文件或符号链接):

/* Remove the copy right header from all files inside project. */
import java.io.IOException;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Pattern;

public class RemoveHeaders {
    private static String readEntireFile(String filePath) {
        String content = "";
        try {
            content = new String(Files.readAllBytes(Paths.get(filePath)));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return content;
    }

    private static void saveFileToDisk(String filePath, String content) {
        File file = new File(filePath);
        Path path = Paths.get(filePath);
        try (FileWriter writer = new FileWriter(file)) {
            if (Files.isWritable(path) && !Files.isSymbolicLink(path) && !Files.isHidden(path)) {
                writer.write(content);
                writer.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static String removeMatchingText(String content, Pattern pattern) {
        return pattern.matcher(content).replaceAll("");
    }

    public static void recursivelyGetFilesAndRemoveHeaders(String path) {
        Pattern copyrightHeader = Pattern.compile("(?i)/\\*(?:\r?\n|\r) ?\\*.*?Copyright[\\S\\s]*?\\*/");
        File currentDirectory = new File(path);
        File[] files = currentDirectory.listFiles();
        if (files == null) {
            return;
        }
        for (File file : files) {
            if (file.isDirectory()) {
                recursivelyGetFilesAndRemoveHeaders(file.getAbsolutePath());
            } else {
                String filePath = file.getAbsolutePath();
                String fileContents = readEntireFile(filePath);
                String updatedContents = removeMatchingText(fileContents, copyrightHeader);
                if (fileContents != updatedContents) {
                    saveFileToDisk(filePath, updatedContents);
                }
            }
        }
    }

    public static void main(String args[]) {
        String rootPath = System.getProperty("user.dir");
        recursivelyGetFilesAndRemoveHeaders(rootPath);
    }
}

为了清晰,我把使用的正则表达式单独列出来:
"(?i)/\\*(?:\r?\n|\r) ?\\*.*?Copyright[\\S\\s]*?\\*/"

现在遇到了麻烦:测试某个文件时,脚本不仅删掉了顶部的版权头,还意外匹配到了文件里第1428行的内容,直接把从那一行到第1554行的所有代码都删掉了!

一开始我以为是文件读取的缓冲问题,特意改用FileInputStream重写了readEntireFile方法,确保流在返回内容前已经关闭,但结果还是一样。

现在我怀疑是不是Java正则表达式引擎的特性导致的?因为我用完全相同的正则模式在JavaScript里测试同一个文件,结果完全符合预期——只匹配并删除了版权头。

附上我的系统和Java版本信息:

openjdk version "1.8.0_171"
OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11)
OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)

已经折腾一整天了,实在搞不懂哪里出问题,恳请各位大佬帮忙排查一下,谢谢!

内容的提问来源于stack exchange,提问作者GrayedFox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:55:52