在使用 Node.js 处理自动生成的 TXT 文件时,常常会遇到格式不规整的情况:版权标记 (C) 被单独列成一行,需要将其合并到上一行的末尾,同时删除多余的空行。通过 fs 模块配合正则表达式可以高效解决,但若方法不当,容易导致数据丢失。
本文将详细介绍如何使用 Node.js 的 `fs` 模块与正则表达式,精准匹配那些仅包含 `(c)` 的独立行,将其合并到上一行末尾,并移除空行。这种自动化文本处理在日志标记、模板生成或文档注释等场景中非常实用,能够显著提升 TXT 文件的格式整洁度。
实际开发中,很多人会尝试编写简单的正则直接替换,例如 `/r?n?.*(C).*$/gm`。然而此方法存在重大缺陷:它会错误匹配那些正文内容中本就含有 `(C)` 字符的行,比如 `Wor(C)d1`,导致整行被替换为 " (C)",造成数据丢失。我们的目标仅仅是移除那些孤立的 (C) 行,而不是破坏正文中的同类字符。
那么,正确的做法是什么?其实只需三步:
- 精确识别完全独立的 (C) 行——该行仅包含空格和 (C),无其他字符;
- 合并到上一行尾部——在上一行末尾添加一个空格并拼接 (C);
- 移除原行并清理残留空行——确保最终格式干净整齐。
下面这段代码是经过打磨的、健壮且通用的实现方案:
const fs = require('fs');
function mergeCLine(filePath) {
const content = fs.readFileSync(filePath, 'utf8');
// 匹配:行首可选空白 + (C) + 行尾可选空白,且前后均有换行(或开头/结尾)
// 使用捕获组保留前一行,并安全替换
const result = content
.replace(/(^|n)([^n]+?)s*ns*(C)s*(?=n|$)/g, '$1$2 (C)')
.replace(/ns*(C)s*$/g, ' (C)'); // 处理文件末尾的 (C)
fs.writeFileSync(filePath, result);
return result;
}
// 示例调用
console.log(mergeCLine('./myFile.txt'));
这里有几个关键点值得详细说明:
- 正则 `/^(n|^)([^n]+?)s*ns*(C)s*(?=n|$)/gm` 中的 `([^n]+?)` 能精准捕获前一行的非空内容,避免误删整行数据;
- `(?=n|$)` 是正向先行断言,确保 (C) 后面要么是换行要么是文件结尾,防止匹配跨行内容;
- 使用两次 `replace` 是为了覆盖所有位置——中间行和文件末尾都需要处理;
- 采用同步的 `readFileSync` 和 `writeFileSync`,可轻松嵌入文件生成流程,无需处理异步回调。
当然,使用时需要注意以下几点:
- 该方案默认支持 Unix (`n`) 和 Windows (`rn`) 换行符。如果要求严格兼容 `rn`,可将正则中的 `n` 替换为 `(rn|n)`。
- 若文本中存在多个 (C) 行需要逐个向上合并(例如嵌套结构),则应改用逐行解析的数组遍历方式,否则会混乱。
- 生产环境中建议添加 try/catch 包住异常,同时检查文件是否存在以及编码是否为 UTF-8,避免意外报错。
总的来说,这种方案简洁可靠,可以无缝嵌入到你的构建脚本或后端服务中。每次生成 TXT 文件后自动执行一遍,格式就能得到完美修正,省心又高效。
