我目前正在尝试在Javascript中构建一个小模板引擎,方法是将html5标签中的标签替换为find并替换为正则表达式。
我在正则表达式上使用exec而且我正在循环结果。我想知道为什么正则表达式在当前形式中以正则表达式上的/ g标志中断,但没有它会好吗?
检查损坏的示例并删除正则表达式上的/ g标志以查看正确的输出。
var TemplateEngine = function(tpl, data) {
var re = /(?:<|<)%(.*?)(?:%>|>)/g, match;
while(match = re.exec(tpl)) {
tpl = tpl.replace(match[0], data[match[1]])
}
return tpl;
}
https://jsfiddle.net/stephanv/u5d9en7n/
有人可以向我详细解释为什么我的例子完全打破了:
<p><%more%></p>
答案 0 :(得分:1)
点击此链接https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex。使用g标志时,存储正则表达式的对象(重新)将跟踪lastIndex
属性中最后一个匹配的位置,下次使用该对象时,搜索将从lastIndex
。
要解决此问题,您可以每次手动重置lastIndex
属性,也可以不将正则表达式保存在对象中并像内联使用它一样:
while(match = /(?:<|<)%(.*?)(?:%>|>)/g.exec(tpl)) {
答案 1 :(得分:1)
原因在javascript string exec strange behavior中解释。
您需要的解决方案实际上是String.replace
,其中有一个回调代替:
var TemplateEngine = function(tpl, data) {
var re = /(?:<|<)%(.*?)(?:%>|>)/g, match;
return tpl.replace(re, function($0, $1) {
return data[$1] ? data[$1] : $0;
});
}
这里,正则表达式按顺序查找字符串中的所有非重叠匹配,并将匹配传递给回调方法。 $0
是完整匹配,$1
是第1组内容。如果data[$1]
存在,则用于替换整个匹配,否则,将插回整个匹配。