
本文详解如何在 Java 中正确使用正则表达式匹配并删除每行开头的第一个字符,重点解决 ^. 默认不跨行生效的问题,并提供带 Pattern.MULTILINE 标志的完整解决方案、代码示例及关键注意事项。
本文详解如何在 java 中正确使用正则表达式匹配并删除每行开头的第一个字符,重点解决 `^.` 默认不跨行生效的问题,并提供带 `pattern.multiline` 标志的完整解决方案、代码示例及关键注意事项。
在 Java 中,正则表达式 ^. 本意是“匹配行首的任意单个字符”,但默认情况下 ^ 仅匹配整个输入字符串的开头,而非每一行的开头。这就是为什么你原始代码中只有第一行的首字符被删除——replaceAll("^.", "") 未启用多行模式(multiline mode),导致 ^ 无法在换行符 \n 后重新锚定到下一行开头。
要实现“对每一行都删除首字符”,必须启用 Pattern.MULTILINE 模式。Java 提供两种等效方式:
✅ 方式一:使用 Pattern.compile() 显式指定标志(推荐)
import java.util.regex.Pattern;
public class RemoveFirstCharPerLine {
public static void main(String[] args) {
String inString = "Z302052023CFCL11 0000.000000000 249999.990 0999999990000.000000000 0000.000000000 0000.000000000 0000.000000000\n" +
"Z302052023CFCL11 0000.000000000 249999.990 0999999990000.000000000 0000.000000000 0000.000000000 0000.000000000";
// ✅ 正确:启用 MULTILINE 模式,使 ^ 匹配每行开头
String result = Pattern.compile("^.", Pattern.MULTILINE)
.matcher(inString)
.replaceAll("");
System.out.println(result);
// 输出(每行首 'Z' 均被移除):
// 302052023CFCL11 0000.000000000 ...
// 302052023CFCL11 0000.000000000 ...
}
}
✅ 方式二:使用内联标志 (?m)(简洁写法)
String result = inString.replaceAll("(?m)^.", "");
(?m) 是正则表达式的内联标志,等价于 Pattern.MULTILINE,作用于其后的整个表达式,同样使 ^ 和 $ 分别匹配每行起始与结束位置。
⚠️ 重要注意事项:
- ❌ String.replaceAll("^.", "") 永远无效——它隐式使用 Pattern.compile("^.")(无标志),^ 仅匹配整个字符串开头;
- ✅ 换行符必须为 \n(Unix/Linux/macOS 风格)或 \r\n(Windows)。Java 的 Pattern.MULTILINE 对 \r\n 同样有效,但需确保字符串真实包含换行符(而非字面量 \n);
- ? 若需提取首字符(而非删除),可用 Pattern.compile("^(.)", Pattern.MULTILINE).matcher(str).results().map(m -> m.group(1)).toArray(String[]::new);;
- ? 对于超大文本,建议使用 Matcher 的 appendReplacement() + appendTail() 进行流式处理以避免内存压力。
总结:正则中的 ^ 行首锚点在 Java 中默认不具备“逐行”语义;启用 MULTILINE 是跨行处理的必要前提。掌握 (?m) 或 Pattern.MULTILINE,即可精准、高效地实现每行首字符的定位与操作。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











