
使用Java 8兼容的单行正则表达式,通过负向断言与分组捕获,可优雅地将字符串中恰好连续2个或9个换行符分别缩减为1个或8个,避免多层if和重复replace调用。
使用java 8兼容的单行正则表达式,通过负向断言与分组捕获,可优雅地将字符串中**恰好连续2个或9个换行符**分别缩减为1个或8个,避免多层if和重复replace调用。
要实现“仅当出现恰好2个或恰好9个连续换行符时,各自减去1个(即变为1个或8个)”,关键在于精确匹配边界——既不能误伤1个、3个、10个等其他数量的换行序列,也不能影响位于更大换行块中的子串(如10个换行中的前9个)。
推荐解法如下:
str = str.replaceAll("(?<!\n)(\n{8}|\n)\n(?!\n)", "$1");✅ 正则解析:
(?:负向先行断言,确保匹配位置<strong>前面不是换行符</strong>(即换行序列起始位置);-
(\n{8}|\n):捕获组,匹配8个换行符(对应原始9个中的前8个)或1个换行符(对应原始2个中的第1个); -
\n:紧随其后的第9个或第2个换行符(即要被删除的那个); -
(?!\n):负向后行断言,确保该换行符后面不是换行符(即序列在此结束,排除≥10或≥3的情况); -
$1:替换为捕获组内容,即保留前8个或前1个,自然实现“9→8”和“2→1”。
? 示例验证:
输入:"1234
4321foo1234
4321"
→ 匹配到
(位置:1234后)→ 替换为
;
→ 匹配到
(9个)→ 替换为
(8个);
输出:"1234
4321foo1234
4321" ✅
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- Java中反斜杠需双写,
写作\n,断言中的(? 不可简写为 <code>(?(否则编译错误); - 该正则严格区分“恰好”数量:
1、3、10个换行符均不匹配,安全无副作用; - 若字符串含混合行分隔符(如
),需先标准化为统一换行符(如str.replace(" ", " "))再应用此正则; - 性能高效,单次
replaceAll完成全部替换,无需循环或状态判断。
此方案简洁、健壮、符合Java 8语法要求,是处理此类“条件性换行压缩”的最佳实践。


















