JS正则表达式只替换重复块的第一个块中的内容

时间:2015-11-16 14:39:17

标签: javascript regex html5

我试图实现一个简单的模板引入javascript。我试图用正则表达式填充模板。

是否可以安全地仅替换模板块的第一次出现而留下第二次未连接?正则表达式如何看待这个?

我确实有一个带有如下构建块的模板(由于块看起来不同,因此实际上有点复杂):

<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");

然而,这种正则表达式导致例如问题。替换第一个块,因为缺少%% c %%,因此在第二个块中替换了%% c %%。但是,我无法使<template>花边仅与第一次出现相匹配。

1 个答案:

答案 0 :(得分:1)

您只需按两个步骤进行操作:

  1. 匹配整个第一个区块。
  2. 处理其内容以替换占位符。
  3. 然后,您可以重新注入新内容,同时删除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);
    }
    

    演示:http://jsfiddle.net/o7tdycme/