Java行尾大括号判断异常:endsWith("\\{")始终返回false的原因及解决
问题原因与解决方案
核心问题:混淆了普通字符串方法与正则方法的转义规则
你这里踩了一个很常见的坑——把正则表达式的转义规则错误用到了普通字符串方法上。
String.endsWith()是普通字符串匹配方法,它会直接匹配字面量内容,不需要对{做任何转义。而你写的endsWith("\\{")实际上是在检查行是否以"\{"(也就是一个反斜杠加左大括号)结尾,但你的源文件里的行是直接以{结尾的,没有前置反斜杠,所以这个判断永远返回false。
而当你改成endsWith(";")时,因为;在正则和普通字符串里都没有特殊含义,普通匹配自然能正常工作。
额外的潜在bug:replaceAll的正则转义问题
你的代码里还有一个隐藏的异常风险:replaceAll("{", "")会抛出PatternSyntaxException,因为{在正则表达式中是特殊字符(用来表示重复次数,比如{2,3}),必须用两个反斜杠转义才能匹配字面量的{,也就是应该写成replaceAll("\\{", "")。
循环索引的逻辑漏洞
另外,你手动管理索引i的方式很容易出错,比如满足条件时执行了两次i++,大概率会导致索引越界或者跳过部分行。更稳妥的方式是直接处理每一行,不需要手动维护索引。
修改后的完整代码
这里是修正后的代码,解决了上述所有问题:
import java.io.File; import java.io.PrintWriter; import java.util.Scanner; public class BraceConverter { public static void main(String[] args) throws Exception { if (args.length != 2) { System.err.println("Error: 2 arguments are required for the program to be executed"); return; // 参数错误直接退出,避免后续无效执行 } File sourceFile = new File(args[0]); File newFile = new File(args[1]); if (!sourceFile.exists()) { System.err.println("Error: source file " + args[0] + " does not exist."); return; } try (Scanner input = new Scanner(sourceFile); PrintWriter output = new PrintWriter(newFile)) { while (input.hasNext()) { String line = input.nextLine(); // 先处理行尾可能的空格,确保判断准确 String trimmedLine = line.trim(); if (trimmedLine.endsWith("{")) { // 去掉行尾的{,保留原行的格式(比如前置空格) String newLine = line.substring(0, line.lastIndexOf("{")); output.println(newLine); output.println("{"); } else { output.println(line); } } } } }
关键修改说明
- 将
endsWith("\\{")改为endsWith("{"),直接匹配字面量左大括号。 - 替换
replaceAll的用法,改用substring去掉行尾的{,既避免了正则转义的麻烦,也更高效直观。 - 去掉了手动维护的
ArrayList和索引i,改为边读边处理边写入,代码更简洁,也规避了索引错误。 - 增加
return语句,在参数错误或文件不存在时直接退出,避免后续不必要的代码执行。 - 增加了行尾空格处理:通过
trim()判断,同时用lastIndexOf保留原行的前置格式(比如缩进空格),保证转换后的代码格式符合预期。
内容的提问来源于stack exchange,提问作者Ryan Foster
相关产品推荐
相关产品推荐

