
本文介绍使用正则表达式精准匹配带编号的句子(如“1. foo. 2. bar.”),并插入换行符实现结构化换行,避免误拆标点,适用于 api 返回的紧凑编号文本处理。
本文介绍使用正则表达式精准匹配带编号的句子(如“1. foo. 2. bar.”),并插入换行符实现结构化换行,避免误拆标点,适用于 api 返回的紧凑编号文本处理。
在实际开发中,尤其是处理 API 返回的自然语言格式文本时,常会遇到类似 "1. foo. 2. bar. 3. baz." 这样的紧凑编号字符串。目标是将其转换为清晰的多行格式:
1. foo. 2. bar. 3. baz.
直接使用 split('.') 或 replace(/\./g, '\n') 会破坏句末句号、导致编号错乱(如将 "foo." 拆成 "foo" 和空字符串),因此必须基于语义模式而非简单字符进行分割。
✅ 推荐方案:使用 String.prototype.replace() 配合负向先行断言(negative lookbehind)正则表达式,精准定位每个编号项的起始位置(即非行首的 \d+\.\s+ 模式),并在其前插入换行符:
const text = "1. foo. 2. bar. 3. baz."; const formatted = text.replace(/(?<!^)\s*(\d+\.\s+)/g, '\n$1').trim(); console.log(formatted); // 输出: // 1. foo. // 2. bar. // 3. baz.
? 正则解析:
立即学习“Java免费学习笔记(深入)”;
- (?
- \s*:匹配编号前可能存在的任意空白(如空格、制表符),提升容错性;
- (\d+\.\s+):捕获组,匹配一个或多个数字 + 字面量 . + 至少一个空白字符(如 "1. "、"10. ");
- '\n$1':用换行符 + 原始匹配内容替换,保留原始格式;
- .trim():清除开头可能残留的空白,确保输出整洁。
⚠️ 注意事项:
- 若原文末尾无空格(如 "3. baz." 后紧跟换行),建议在正则中补充对结尾边界的兼容,或统一预处理:text.replace(/\s+$/g, ' ');
- 若编号后不总跟空格(如 "1.foo."),可将 \s+ 改为 \s* 并增强捕获逻辑,例如:/(\d+\.\s*)/g,再结合 split() 与 filter() 进一步清洗;
- 在不支持 (?
? 总结:该方法以语义为中心,兼顾健壮性与可读性,是处理编号列表格式化的轻量级标准解法。掌握此类正则模式,可快速适配 4. qux. 5. quux. 等任意长度编号序列,无需循环或复杂状态管理。










