JavaScript替换/正则表达式


113

给定此功能:

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

Answers:


147

您需要对所有RegExp字符进行两次转义(一次用于字符串中的斜杠,一次用于regexp):

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

否则,它将查找该行的末尾和“ TESTONE”(它从未找到)。

就个人而言,出于这个原因,我不是构建使用字符串的regexp的忠实粉丝。逃逸的水平可能会导致您喝酒。我敢肯定,其他人在编写正则表达式时会有所不同,喜欢喝酒。


但是replace()接收正则表达式作为变量。
核心

8
@Chris-如果您使用,我认为这没有什么不同 /pattern/或,new RegExp("pattern")
harto

@seth,您的答案有效,但是它不能为OP中的代码提供解决方案。我该如何调用OP的代码?
黑色

82

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

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

如果您想使用replace方法替换文字字符串,我认为您可以将字符串而不是regexp传递给replace

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

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

// ...

var re = new RegExp(reEscape(pattern), "mg");
this.markup = this.markup.replace(re, value);

12
之前不知道,/ pattern /与新的RegExp(“ pattern”)相同。真的有帮助!
Nik Sumeiko

1
有什么理由不使用白名单而不是黑名单?例如:s.replace(/(\ W)/ g,'\\ $ 1')
greg.kindel 2013年

1
列出的第一种形式更好。避免使用new关键字是一个好习惯。
德鲁斯卡

2
说正则表达式文字(/ regex /)与RegExp(“ regex”)相同是不准确的。在正则表达式文字中,反斜线('\')本身不需要转义('\\')即可成为正则表达式的一部分。此外,可以在解析脚本时而不是每次执行函数时编译正则表达式文字。为了匹配反向固相线,您可以编写/ \\ /或RexExp(“ \\\\”)。
约翰

31

您的正则表达式模式应具有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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.