
本文详解如何在Java中正确使用正则表达式匹配并删除多行字符串中每一行的首个字符,重点解决^.默认不跨行生效的问题,并提供带Pattern.MULTILINE标志的可靠实现方案。
本文详解如何在java中正确使用正则表达式匹配并删除多行字符串中每一行的首个字符,重点解决`^.`默认不跨行生效的问题,并提供带`pattern.multiline`标志的可靠实现方案。
在Java中,正则表达式 ^. 本意是“匹配行首的任意一个字符”,但默认情况下,^ 仅匹配整个输入字符串的开头,而非每行开头。这就是为什么你调用 inString.replaceAll("^.", "") 后,只有第一行的首字符被移除——因为 replaceAll() 使用的是 java.util.regex 的默认模式(DOTALL 和 MULTILINE 均未启用),^ 不具备“每行起始”的语义。
要让 ^ 真正匹配每一行的开头,必须显式启用 MULTILINE 模式。有两种等效方式:
✅ 推荐方式一:使用 Pattern.compile(..., Pattern.MULTILINE) + Matcher
import java.util.regex.Pattern;
import java.util.regex.Matcher;
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 模式,使 ^ 匹配每行开头
Pattern pattern = Pattern.compile("^.", Pattern.MULTILINE);
String result = pattern.matcher(inString).replaceAll("");
System.out.println(result);
/* 输出:
302052023CFCL11 0000.000000000 249999.990 0999999990000.000000000 0000.000000000 0000.000000000 0000.000000000
302052023CFCL11 0000.000000000 249999.990 0999999990000.000000000 0000.000000000 0000.000000000 0000.000000000
*/
}
}
✅ 简洁方式二:使用内嵌标志 (?m)(推荐用于单行正则)
String result = inString.replaceAll("(?m)^.", "");
(?m) 是 MULTILINE 模式的内嵌标志,作用于其后的整个正则表达式,效果与 Pattern.MULTILINE 完全一致,且更轻量。
⚠️ 注意事项:
- ❌ inString.replaceAll("^.", "") —— 错误:无 MULTILINE,仅替换首行首字符;
- ✅ inString.replaceAll("(?m)^.", "") —— 正确:(?m) 开启多行模式;
- ✅ Pattern.compile("^.", Pattern.MULTILINE).matcher(inString).replaceAll("") —— 更可控,适合复杂场景(如需捕获、回调等);
- \n 必须存在(即字符串含换行符),否则即使开启 MULTILINE 也只有一行可匹配;
- 若需保留空行首字符(如空行 ""),^. 不会匹配(因 . 不匹配换行符),这是预期行为;如需处理空行,可用 ^. 或 ^\S? 等逻辑另行设计。
? 延伸:提取每行首字符(类似Python示例)
若目标是获取而非删除首字符,可使用 Pattern + Matcher.find():
List<string> firstChars = new ArrayList();
Matcher m = Pattern.compile("(?m)^.").matcher(inString);
while (m.find()) {
firstChars.add(m.group());
}
System.out.println(firstChars); // [Z, Z]</string>
总结:在Java中操作多行文本时,切记 ^ 和 $ 的行为受 MULTILINE 标志控制;脱离该标志的 ^. 无法满足“逐行处理”需求。始终优先使用 (?m)^. 或显式编译带 Pattern.MULTILINE 的正则对象,确保逻辑健壮、结果可预期。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











