正则表达式全局替换不替换第一次出现

时间:2017-01-23 02:34:57

标签: javascript regex

我试图进行快速而肮脏的模板测试,但是当正则表达式替换时,它只替换最后一次出现,我认为\g将替换所有副本。但它只匹配最后一次出现。

How to String.match() distinct it ${SOME_TEXT} using Regex

我尝试做的是为每个唯一变量名称提示用户一次。

Title = t
name = n
result = '${Title} - n - t'

使用/\$\{([^\}]+)\}/g有效,但会多次提示用户。

Title = t
name = n
Title = t
result = 't - n - t'

那么无论出现多少次,我怎样才能用一个值替换每个标记。

<html>
<head>
    <script type="application/javascript">

        window.copyToClipboard = function(n) {
            var u = "_hiddenCopyText_", t, i, r;
            t = document.getElementById(u);
            t.textContent = n;
            i = document.activeElement;
            t.focus();
            t.setSelectionRange(0, t.value.length);
            try {
                r = document.execCommand("copy")
            } catch (f) {
                r = !1
            }
            return i && typeof i.focus == "function" && i.focus(),
                t.textContent = "",
                r
        };
        //${varname}
        window.templateRegex = /\$\{([^\}]+)\}(?![\S\s]*\$\{\1\})/g;
        window.test = " ${Title} - ${Name} - ${Title}"
        window.copyTemplate = function (template) {
            var result = template.replace(window.templateRegex, function(match, token){
               return window.prompt("replace value for ${"+token+"}","${"+token+"}");
            });
            window.copyToClipboard(result);
        };

    </script>
</head>
<textarea id="_hiddenCopyText_"></textarea>
<button onclick="copyTemplate(window.test)">Test</button>
</html>

JsFiddle https://jsfiddle.net/ksu37c3b/

2 个答案:

答案 0 :(得分:1)

如果多次出现${..}($ {Title}),/\$\{([^\}]+)\}(?![\S\s]*\$\{\1\})/g只会匹配最后一个。要匹配所有元素,/\$\{([^\}]+)\}/g将起作用,它不需要否定前瞻(?![\S\s]*\$\{\1\})
在字符串"${Title} - ${Name} - ${Title}"中,只有${Name}${Title}匹配模式,因为第一个和最后一个是相同的,如果您更改字符串,例如{{1}它将匹配所有元素,因为$ {Title2}和$ {Title}不相等。这是"${Title2} - ${Name} - ${Title}"尝试做的事情,如果最后(?![\S\s]*\$\{\1\})和当前${..}相同,则不会匹配。

更新

  

那么无论出现多少次,我怎样才能用一个值替换每个标记。

您可以使用${..}方法获取一系列令牌,然后逐个替换它,下面的代码将起作用:

&#13;
&#13;
match()
&#13;
&#13;
&#13;

我修改了您的代码,如下所示:

&#13;
&#13;
window.templateRegex = /\$\{([^\}]+)\}(?![\S\s]*\$\{\1\})/g;
window.test = " ${Title} - ${Name} - ${Title}";
var userinput, reg, i;
var arr = window.test.match(/\$\{([^\}]+)\}(?![\S\s]*\$\{\1\})/g);
for (i = 0; i < arr.length; i++) {
    arr[i] = arr[i].replace(/[\$\{\}]/g, "");
    userinput = window.prompt("replace value for " + arr[i]);
    reg = new RegExp("\\$\\{" + arr[i] + "\\}", 'g');
    console.log(reg);
    window.test = window.test.replace(reg, userinput);
}
alert(window.test);
&#13;
window.copyToClipboard = function(n) {
  var u = "_hiddenCopyText_",
    t, i, r;
  t = document.getElementById(u);
  t.textContent = n;
  //** snip **//
};
//${varname}
window.templateRegex = /\$\{([^\}]+)\}(?![\S\s]*\$\{\1\})/g;
window.test = " ${Title} - ${Name} - ${Title}";
window.copyTemplate = function(template) {
    var result = template;
    var userinput, reg;
    var arr = result.match(/\$\{([^\}]+)\}(?![\S\s]*\$\{\1\})/g);
    for (let i = 0; i < arr.length; i++) {
        arr[i] = arr[i].replace(/[\$\{\}]/g, "");
        userinput = window.prompt("replace value for " + arr[i]);
        reg = new RegExp("\\$\\{" + arr[i] + "\\}", 'g');
        console.log(reg);
        result = result.replace(reg, userinput);
    }
    window.copyToClipboard(result);
};
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这应该做你想要的init(name: String?, uid: String?, email: String?, username: String?)

我刚刚在负向前方的中间删除*,因为它导致它每次匹配最后一次。