我正在尝试匹配模板文字中的所有匹配项<% anything %>
。
我的正则表达式设置如下所示。
process(template : string , data: Object) {
let re = /<%([^%>]+)?%>/g, match;
while (match = re.exec(template)) {
template = template.replace(match[0], data[match[1]]);
}
return template;
}
如果我的模板看起来像这样
`<div class="tile">
<span><%ENTRY_NUMBER%></span>
<span><%NAME%> , <%CLASS%> , <%GENDER%> , <%AGE%></span>
</div>`
它会匹配第一次出现就好了,然后继续选择备用事件。如果html标签内有一个匹配它可以正常工作,但是当我使用第二个span元素中的倍数时,它会错过交替出现。我认为它与&lt;和&gt;。
当我将这些事件与<>
而不是像下面的逗号分开时,它可以正常工作。
<span><%NAME%> <> <%CLASS%> <> <%GENDER%> <> <%AGE%></span>
这样的结果
<span> john <> biology <> male <> 17 </span>
我已多次检查正则表达式,但无济于事。
答案 0 :(得分:2)
问题在于re.lastIndex
存储的值是template
之前的值,但是由于您更改了template
值,re.lastIndex
不再正确对于修改后的字符串。
请参阅下面的简化示例:
let template = `<%ENTRY_NUMBER%><%NAME%><%CLASS%><%GENDER%><%AGE%>`;
let re = /<%(.+?)%>/g, match;
let data = { 'NAME':'John', 'CLASS':'A3', 'GENDER':'Male', 'AGE':'19' };
while (match = re.exec(template)) {
console.log(re.lastIndex);
template = template.replace(match[0], data[match[1]]);
console.log(template);
}
console.log(template);
// Iteration 1: re.lastIndex = 16
// undefined<%NAME%><%CLASS%><%GENDER%><%AGE%>
// Index is now between <%NAME% and > -> this match will be skipped
// and so on...
因此,最好在替换回调中动态修改字符串,因为一旦找到它们就会替换所有匹配项,并且您不必跟踪索引的搜索位置。
使用
process(template : string , data: Object) {
return template.replace(/<%(.+?)%>/g, function($0, $1) {
return data[$1] ? data[$1] : $0;
});
}
请注意,<%(.+?)%>
匹配<%
,然后捕获除换行符之外的任何1个或多个字符,尽可能少地进入第1组,然后匹配%>
。这样,您还会匹配包含%
和>
的值(如果data
包含此类密钥,则非常重要。)
答案 1 :(得分:0)
问题是你不需要全局标记g
,因为你反复重复执行表达式,直到不匹配,但是多行标记m
let s = `<div class="tile">
<span><%ENTRY_NUMBER%></span>
<span><%NAME%> , <%CLASS%> , <%GENDER%> , <%AGE%></span>
</div>`;
const re = /<%([^\%]+)?%>/,
data = {
ENTRY_NUMBER: '1977',
NAME: 'Blue',
CLASS: 'Vertebrates',
GENDER: 'Male',
AGE: '40'
};
let k = 0;
while (re.test(s) && k++ < 1000) {
match = re.exec(s);
if (match) s = s.replace(match[0], data[match[1]]);
}
console.log(s);
&#13;