Node.js批量替换stations.js内日文名称字段 暂用固定值测试后续对接Google翻译API
批量修改stations.js中name字段的可落地实现方案
为什么之前的正则提取+字符串拼接实现容易不通
你目前采用的正则匹配提取name映射、手工拼接新文件的思路,天生存在容易出bug的硬伤:
- 普通正则很难精准匹配带转义字符、换行的日文name值,很容易出现引号截断、匹配错位的问题
- 手工拼接生成新文件的过程,会完全丢失原文件的原有格式(比如缩进风格、字段书写顺序、行内注释、特殊字符的书写方式),根本做不到“除了name字段其余内容完全保留、结构和原文件一致”的要求
- 一旦匹配逻辑出偏差,很容易误改其他字段的内容,没有兜底校验的话很容易损坏原始站点数据
正确的实现路径
核心原则:只精准替换目标name字段对应的文本片段,其他原文件内容一字节都不做改动,完全避开全量重拼文件的逻辑
流程拆成4步:
- 读取原stations.js的纯文本内容,不直接
require导入模块(require拿到的是解析后的JS对象,序列化回字符串会完全丢失原格式) - 定位到文件中所有属于站点对象的name字段值的精确文本位置,拿到原始日文字符串
- 对每个定位到的片段,从文件末尾往开头依次替换内容:从后往前替换可以完全避免替换导致的文本长度变化、索引错位问题,替换时保持原有的字符串包裹格式(比如原片段用单引号就保留单引号,用双引号就保留双引号)
- 替换完成后把新文本写入临时的测试文件,和原文件做diff对比,确认仅name字段的值发生变化后,再正式替换原文件
测试阶段的最小可运行代码示例
const fs = require('fs/promises'); const path = require('path'); // 占位翻译函数,测试阶段固定返回"hello" // 后续对接Google翻译API时,仅需修改这个函数的内部逻辑,不需要改动其他流程 async function getTranslateResult(jpName) { return "hello"; } async function runReplace() { // 读取原文件纯文本 const originalContent = await fs.readFile( path.resolve(__dirname, './stations.js'), 'utf-8' ); // 匹配所有name键值对的正则,根据你原文件的书写格式调整匹配规则 // 这里匹配逻辑适配原文件中name的书写格式为 name: "日文值", const nameMatchReg = /(\s*name:\s*["'])(.*?)(["'],?)/g; const matchList = []; // 先收集所有匹配结果的位置和值,不做即时替换 let match; while ((match = nameMatchReg.exec(originalContent)) !== null) { matchList.push({ startIndex: match.index + match[1].length, endIndex: nameMatchReg.lastIndex - match[3].length, originalName: match[2] }) } // 从后往前逐段替换,避免索引错位 let newContent = originalContent; for (let i = matchList.length - 1; i >= 0; i--) { const item = matchList[i]; const translatedName = await getTranslateResult(item.originalName); // 切片替换对应位置的文本,其他内容完全不动 newContent = newContent.slice(0, item.startIndex) + translatedName + newContent.slice(item.endIndex); } // 先写到测试文件,验证没问题再覆盖原文件 await fs.writeFile( path.resolve(__dirname, './stations.test.js'), newContent, 'utf-8' ); console.log('替换完成,请检查stations.test.js内容是否符合预期'); } runReplace().catch(err => console.error('执行出错:', err));
避坑提醒
- 第一次运行脚本时务必备份原stations.js文件,避免脚本逻辑偏差损坏原始数据
- 正则匹配规则要和你原文件的书写格式对齐:比如如果原文件的name值用反引号包裹、或者值后面没有逗号,要对应调整正则的匹配片段,不然会出现匹配遗漏或者错位
- 从后往前替换的顺序不要搞反,不然先替换靠前的文本时,新字符串的长度和原字符串不一致,会导致后面收集的索引位置全部偏移,替换错位置
内容的提问来源于stack exchange,提问作者Gajiu
相关产品推荐
相关产品推荐

