我正在尝试用 JavaScript 实现一个简单的模板引擎。我正在尝试用正则表达式填充模板。
是否可以安全地仅替换第一次出现的模板 block ,同时不附加第二次出现的模板 block ?正则表达式必须如何查找这样的内容?
我确实有一个包含如下构建 block 的模板(实际上有点复杂,因为 block 看起来不同):
<template-block>
<h1>%%a%%</h1>
<img src="%%b%%" />
</template-block>
<template-block>
<h1>%%a%%</h1>
<img src="%%b%%" />
<p>%%c%%</p>
</template-block>
<template-block>
<h1>%%a%%</h1>
<img src="%%b%%" />
<p>%%c%%</p>
</template-block>
现在的替换是通过以下表达式完成的
html = html.replace(/(<template-block>.+?)%%a%%(.*<\/template-block>)/gim,"$1"+a+"$2");
html = html.replace(/(<template-block>.+?)%%b%%(.*<\/template-block>)/gim,"$1"+b+"$2");
html = html.replace(/(<template-block>.+?)%%c%%(.*<\/template-block>)/gim,"$1"+c+"$2");
html = html.replace(/(<template-block>)([\s\S]+?)(<\/template-block>)/gim,"$2");
但是这个正则表达式会导致问题,例如在替换第一个 block 时,因为缺少 %%c%%,因此 %%c%% 在第二个 block 中被替换。但是我无法制作 <template>
lacy 仅匹配它的第一次出现。
最佳答案
您只需执行两步即可:
- 匹配整个第一个 block 。
- 处理其内容以替换您的占位符。
然后您可以重新注入(inject)新内容,同时删除 template-block
标记。
var re = /(<template-block>)([\s\S]*?)(<\/template-block>)/i,
a = "aa", // whatever value you need.
b = "bb",
c = "cc",
newHtml;
function processFirstBlock(text) {
var firstBlockContent = re.exec(text),
innerContent;
if (firstBlockContent && firstBlockContent.length) {
// firstBlockContent[2] is what is matched with ([\s\S]*?)
innerContent = firstBlockContent[2];
innerContent = innerContent.
replace(/(%%a%%)/gi, a).
replace(/(%%b%%)/gi, b).
replace(/(%%c%%)/gi, c);
// firstBlockContent[0] is the entire match.
// [1] and [3] are the opening and closing tags, so drop them.
text = text.replace(firstBlockContent[0], innerContent);
return text;
}
return false;
}
newHtml = processFirstBlock(html);
while (newHtml) {
html = newHtml;
newHtml = processFirstBlock(html);
}
关于javascript - JS正则表达式仅替换重复 block 的第一个 block 中的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33737946/