多行正则全局搜索替换:Handlebars转Nunjucks代码实现
实现方案:Handlebars 转 Nunjucks 批量递归转换
完全可以实现这个批量转换需求,以下是针对正则替换和递归文件处理的可行方案:
一、精准正则替换规则
你之前的正则仅部分生效,大概率是没处理换行、缩进,以及特殊变量映射(比如title→heroTitle)和文件后缀替换(.hbs→.njk)。可以使用带捕获组的多行正则配合自定义替换逻辑完成转换:
正则表达式(匹配Handlebars Partial块)
{{>\s*(\w+-?\w+)\s+((?:\s*\w+=(?:"[^"]+"|\w+))+)}}
- 捕获组1:匹配Partial名称(比如
default-hero) - 捕获组2:匹配所有属性键值对(比如
color="red" title="Foo")
替换逻辑(以JavaScript为例)
对捕获到的内容做针对性处理:
- 将
title映射为heroTitle - 将
.hbs后缀替换为.njk - 布尔值(如
true/false)保留原样,字符串值保留引号 - 每个键值对转为
{% set 键 = 值 %}格式 - 最后生成
{% include "partial名.njk" %}
示例替换函数:
function convertHbsToNunjucks(hbsCode) { const regex = /{{>\s*(\w+-?\w+)\s+((?:\s*\w+=(?:"[^"]+"|\w+))+)}}/ms; return hbsCode.replace(regex, (match, partialName, attrsRaw) => { const attrs = attrsRaw.trim().split(/\s+/); const setLines = attrs.map(attr => { let [key, value] = attr.split('='); if (key === 'title') key = 'heroTitle'; if (value.includes('.hbs')) value = value.replace('.hbs', '.njk'); return `{% set ${key} = ${value} %}`; }); return `${setLines.join('\n')}\n\n{% include "${partialName}.njk" %}`; }); }
二、递归处理多文件
用Node.js的fs模块实现递归遍历目录,对所有.hbs文件执行转换:
const fs = require('fs'); const path = require('path'); function processDir(dirPath) { const files = fs.readdirSync(dirPath); files.forEach(file => { const fullPath = path.join(dirPath, file); const stats = fs.statSync(fullPath); if (stats.isDirectory()) { processDir(fullPath); } else if (path.extname(file) === '.hbs') { const hbsContent = fs.readFileSync(fullPath, 'utf8'); const njkContent = convertHbsToNunjucks(hbsContent); const njkPath = fullPath.replace('.hbs', '.njk'); fs.writeFileSync(njkPath, njkContent, 'utf8'); console.log(`转换完成:${fullPath} → ${njkPath}`); } }); } // 传入目标根目录路径启动转换 processDir('./your-target-directory');
注意事项
- 如果你的Handlebars属性有更复杂格式(比如带空格的字符串、表达式),需调整正则和替换逻辑兼容
- 建议先在测试目录验证结果,再批量处理生产文件
内容的提问来源于stack exchange,提问作者user366810
相关产品推荐
相关产品推荐

