使用字符串变量动态创建正则表达式

2022-08-30 03:07:42

假设我想使以下内容可重用:

function replace_foo(target, replacement) {
   return target.replace("string_to_replace",replacement);
}

我可能会做这样的事情:

function replace_foo(target, string_to_replace, replacement) {
   return target.replace(string_to_replace,replacement);
}

使用字符串文本,这很容易。但是,如果我想使用正则表达式变得更加棘手怎么办?例如,假设我想替换 .本能地,我会尝试通过做这样的事情来扩展上述内容:string_to_replace

function replace_foo(target, string_to_replace, replacement) {
   return target.replace(/^string_to_replace/,replacement);
}

这似乎不起作用。我的猜测是,它被认为是一个字符串文本,而不是一个表示字符串的变量。是否可以使用字符串变量动态创建 JavaScript 正则表达式?如果可能的话,这样的东西会很棒:string_to_replace

function replace_foo(target, string_to_replace, replacement) {
   var regex = "/^" + string_to_replace + "/";
   return target.replace(regex,replacement);
}

答案 1

有 哪里是 或 .所以new RegExp(string, flags)flagsgi

'GODzilla'.replace( new RegExp('god', 'i'), '' )

评估为

zilla

答案 2

使用字符串文本,这很容易。

没有!该示例仅替换第一次出现的 。更常见的是,您希望替换所有匹配项,在这种情况下,必须将字符串转换为全局 () RegExp。您可以使用构造函数从字符串中执行此操作:string_to_replace/.../gnew RegExp

new RegExp(string_to_replace, 'g')

这样做的问题是,字符串文本中的任何正则表达式特殊字符都将以其特殊方式运行,而不是正常字符。您必须反斜杠转义它们才能解决此问题。不幸的是,没有内置函数可以为您执行此操作,因此您可以使用以下函数:

function escapeRegExp(s) {
    return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
}

另请注意,当您在 中使用正则表达式时,替换字符串现在也具有特殊字符 。如果您希望在替换文本中有文字,也必须对此进行转义!replace()$$

function escapeSubstitute(s) {
    return s.replace(/\$/g, '$$$$');
}

(四个s,因为这本身就是一个替换字符串 - 哎呀!$

现在,您可以使用 RegExp 实现全局字符串替换:

function replace_foo(target, string_to_replace, replacement) {
    var relit= escapeRegExp(string_to_replace);
    var sub= escapeSubstitute(replacement);
    var re= new RegExp(relit, 'g');
    return target.replace(re, sub);
}

真是太痛苦了。幸运的是,如果您只想使用正则表达式的附加部分进行直字符串替换,则有一种更快的方法:

s.split(string_to_replace).join(replacement)

...仅此而已。这是一个通常理解的成语。

说我想替换除string_to_replace

这是什么意思,您想替换所有未参与与字符串匹配的文本的延伸?替换为肯定不会这样,因为这意味着字符串的起始令牌,而不是否定。 只是字符组中的否定。也有负面的期待,但是在JScript中存在问题,因此您通常应该避免使用它。^^^[](?!...)

您可以尝试匹配字符串的“所有内容”,并使用函数丢弃匹配字符串之间的任何空拉伸:

var re= new RegExp('(.*)($|'+escapeRegExp(string_to_find)+')')
return target.replace(re, function(match) {
    return match[1]===''? match[2] : replacement+match[2];
});

同样,在这里,拆分可能更简单:

var parts= target.split(string_to_match);
for (var i= parts.length; i-->0;)
    if (parts[i]!=='')
        parts[i]= replacement;
return parts.join(string_to_match);