1.正则抠出要匹配的内容
针对这一串代码,通过正则获取内容
var tpl = 'Hei, my name is <%name%>, and I\'m <%age%> years old.';
var data = {
"name": "Barret Lee", "age": "20" };
最简单的方式就是通过replace函数了:
var result = tpl.replace(/<%([^%>]+)?%>/g, function(s0, s1){ return data[s1]; });
注:replace()方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
语法:
stringObject.replace(regexp/substr,replacement)
参数 | 描述 |
---|---|
regexp/substr | 必需。规定子字符串或要替换的模式的 RegExp 对象。 请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为 RegExp 对象。 |
replacement | 必需。一个字符串值。规定了替换文本或生成替换文本的函数。 |
返回值
一个新的字符串,是用 replacement 替换了 regexp 的第一次匹配或所有匹配之后得到的。
说明
字符串 stringObject 的 replace() 方法执行的是查找并替换的操作。它将在 stringObject 中查找与 regexp 相匹配的子字符串,然后用 replacement 来替换这些子串。如果 regexp 具有全局标志 g,那么 replace() 方法将替换所有匹配的子串。否则,它只替换第一个匹配子串。
replacement 可以是字符串,也可以是函数。如果它是字符串,那么每个匹配都将由字符串替换。但是 replacement 中的 $ 字符具有特定的含义。
返回一个这样的结果
'Posts: '
for(var i = 0; i < post.length; i++) { '<a href="#">' + post[i].exper + '</a>' }
但是我们需要得到的是一个字符串,而不是上面这样零散的片段,因此可以把这些东西装入数组中。
2.装入数组
var r = [];
r.push('Posts: ' );
for(var i = 0; i < post.length; i++) { r.push('<a href="#">'); r.push(post[i].exper); r.push('</a>'); }
这样的逻辑就十分完善了,不存在太多的漏洞,但是这个转化的过程是如何实现的?我们必须还是要写一个解析的模板函数出来。
3.分辨js逻辑部分
var reg = /<%([^%>]+)?%>/g;
while(match = reg.exec(tpl)) {
console.log(match); }
主要是靠match的index属性来定位遍历位置,然后利用while循环获取所有的内容。
4.引擎函数
我们并需要for,if,switch等这些东西也push到r数组中去,所以呢,还得改善下上面的代码,如果在line中发现了包含js逻辑的代码,我们就不应该让他进门:
regOut = /(^( )?(if|for|else|switch|case|break|{|}))(.*)?/g; var add = function(line, js) { js? code += line.match(regOut) ? line + '\n' : 'r.push(' + line + ');\n' : code += 'r.push("' + line.replace(/"/g, '\\"') + '");\n'; };
所以我们只剩下最后一步工作了,把data扔进去!
5.把data扔进去
var tplEngine = function(tpl, data) { var reg = /<%([^%>]+)?%>/g, regOut = /(^( )?(if|for|else|switch|case|break|{|}))(.*)?/g, code = 'var r=[];\n', cursor = 0; var add = function(line, js) { js? (code += line.match(regOut) ? line + '\n' : 'r.push(' + line + ');\n') : (code += line != '' ? 'r.push("' + line.replace(/"/g, '\\"') + '");\n' : ''); return add; } while(match = reg.exec(tpl)) { add(tpl.slice(cursor, match.index))(match[1], true); cursor = match.index + match[0].length; } add(tpl.substr(cursor, tpl.length - cursor)); code += 'return r.join("");'; return new Function(code.replace(/[\r\t\n]/g, '')).apply(data); };