模板替换及正则捕捉

最近在做关于模板替换的一些练习, 总结了一些经验。
平时当我们需要创建一个HTML元素的时候, 总是需要借助相关的api

1
2
const node = document.createElement('div')
node.className = data

这样显得很繁琐, 累赘, 如果偷懒点也许会写成这样

1
const node = `<div class="${data}"></div>`

但这是ES2015的新语法嘛, 所以我们可以尝试自己制作一个简单的模板替换

1
const node = `<div class="{{data}}"></div>`

如上所示, 我们需要用正则匹配相关变量名, 需要用到string.prototype.replace() 这个api

1
2
3
4
5
6
7
const template = function(tem, data) {
return tem.replace(/{{(\w+)}}/g, function(str, p1) {
if (!p1)
return ""
return data[p1]
})
}

需要了解的是, string.prototype.replace()这个api的第一个参数是需要匹配的正则或是单独的字符串, 第二个参数可以是新的字符串, 也可以是一个function

1
2
3
4
5
6
7
function replacer(match, p1, p2, p3, offset, string) {
// match 代表匹配的子串
// p1,p2, ... 代表被()正则符号捕捉的字符串
// offset 代表匹配子串在原字符串的偏移量
// string 原字符串
return "返回新字符串";
}

如果需要支持对象, 需要对原函数进行改造

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const template = function(tem, data) {
return tem.replace(/{{(\w+(?:\.\w+)*)}}/g, function(match, p1) {
// (?:) 在正则中不会捕捉相关子串, 但可以对其子串合并
if (!p1)
return ""
const arr = p1.split('.')
let datas = data
arr.forEach(function (value, index) {
datas = datas[value] || null
})
return datas
})
}
// 相关调用方法
const templateStr = `{{name}}`
const newStr = template(templateStr, {name:"成功"})
console.log(newStr)

模板内容替换成功
success