JavaScript 替换/正则表达式

IT技术 javascript regex replace
2021-02-19 05:50:41

鉴于此功能:

function Repeater(template) {

    var repeater = {

        markup: template,

        replace: function(pattern, value) {
            this.markup = this.markup.replace(pattern, value);
        }

    };

    return repeater;

};

我如何进行this.markup.replace()全局替换?这就是问题所在。如果我像这样使用它:

alert(new Repeater("$TEST_ONE $TEST_ONE").replace("$TEST_ONE", "foobar").markup);

警报的值为“foobar $TEST_ONE”。

如果我更改Repeater为以下内容,则 Chrome 中不会替换任何内容:

function Repeater(template) {

    var repeater = {

        markup: template,

        replace: function(pattern, value) {
            this.markup = this.markup.replace(new RegExp(pattern, "gm"), value);
        }

    };

    return repeater;

};

...警报是$TEST_ONE $TEST_ONE

3个回答

您需要对任何 RegExp 字符进行双重转义(一次用于字符串中的斜杠,一次用于 regexp):

  "$TESTONE $TESTONE".replace( new RegExp("\\$TESTONE","gm"),"foo")

否则,它会查找行尾和“TESTONE”(它从未找到)。

就个人而言,由于这个原因,我不太喜欢使用字符串构建正则表达式。所需的逃避程度可能会导致您喝酒。我敢肯定,其他人在编写正则表达式时会有不同的感觉,并且喜欢喝酒。

@seth,您的答案有效,但它没有为 OP 中的代码提供解决方案。我该如何调用 OP 的代码?
2021-04-16 05:50:41
但是 replace() 将正则表达式作为变量接收。
2021-04-23 05:50:41
@Chris - 如果您使用/pattern/或 ,我认为这没有什么区别new RegExp("pattern")
2021-05-15 05:50:41

在模式解释方面,以下形式之间没有区别:

  • /pattern/
  • new RegExp("pattern")

如果您想使用该replace方法替换文字字符串,我认为您可以将字符串而不是正则表达式传递给replace.

否则,您必须首先转义模式中的任何正则表达式特殊字符 - 也许像这样:

function reEscape(s) {
    return s.replace(/([.*+?^$|(){}\[\]])/mg, "\\$1");
}

// ...

var re = new RegExp(reEscape(pattern), "mg");
this.markup = this.markup.replace(re, value);
有什么理由不使用白名单而不是黑名单?例如:s.replace(/(\W)/g,'\\$1')
2021-04-16 05:50:41
列出的第一种形式更好。避免使用new关键字是一种很好的做法
2021-04-21 05:50:41
说正则表达式文字 (/regex/) 与 RegExp("regex") 相同是不准确的。在正则表达式文字中,反斜线 ('\') 本身不需要转义 ('\\') 以使其成为正则表达式的一部分。此外,可以在解析脚本时而不是每次执行函数时编译正则表达式文字。为了匹配反向固体,您可以编写 /\\/ 或 RexExp("\\\\")。
2021-04-30 05:50:41
之前不知道,/pattern/ 和 new RegExp("pattern") 是一样的。真的有帮助!
2021-05-05 05:50:41

你的正则表达式模式应该有 g 修饰符:

var pattern = /[somepattern]+/g;

注意末尾的 g。它告诉替换器进行全局替换。

你也不需要使用 RegExp 对象,你可以像上面那样构造你的模式。示例模式:

var pattern = /[0-9a-zA-Z]+/g;

模式总是被 / 包围 - 在最后的 / 后面有修饰符,g 修饰符是全局的。

编辑:为什么模式是变量很重要?在你的情况下,它的功能是这样的(注意模式仍然是一个变量):

var pattern = /[0-9a-zA-Z]+/g;
repeater.replace(pattern, "1234abc");

但是您需要将替换功能更改为:

this.markup = this.markup.replace(pattern, value);