Javascript 使用字符串变量动态创建 RegExp

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4371565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 12:08:04  来源:igfitidea点击:

Create RegExps on the fly using string variables

javascriptregex

提问by buley

Say I wanted to make the following re-usable:

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

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

I might do something like this:

我可能会做这样的事情:

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

With string literals this is easy enough. But what if I want to get a little more tricky with the regex? For example, say I want to replace everything butstring_to_replace. Instinctually I would try to extend the above by doing something like:

使用字符串文字,这很容易。但是,如果我想对正则表达式更加棘手怎么办?例如,假设我想替换string_to_replace. 本能地,我会尝试通过执行以下操作来扩展上述内容:

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

This doesn't seem to work. My guess is that it thinks string_to_replaceis a string literal, rather than a variable representing a string. Is it possible to create JavaScript regexes on the fly using string variables? Something like this would be great if at all possible:

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

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

回答by meder omuraliev

There's new RegExp(string, flags)where flagsare gor i. So

还有new RegExp(string, flags)哪里flagsgi。所以

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

evaluates to

评估为

zilla

回答by bobince

With string literals this is easy enough.

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

Not really! The example only replaces the firstoccurrence of string_to_replace. More commonly you want to replace all occurrences, in which case, you have to convert the string into a global (/.../g) RegExp. You can do this from a string using the new RegExpconstructor:

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

new RegExp(string_to_replace, 'g')

The problem with this is that any regex-special characters in the string literal will behave in their special ways instead of being normal characters. You would have to backslash-escape them to fix that. Unfortunately, there's not a built-in function to do this for you, so here's one you can use:

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

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

Note also that when you use a RegExp in replace(), the replacement string now has a special character too, $. This must also be escaped if you want to have a literal $in your replacement text!

另请注意,当您在 中使用 RegExp 时replace(),替换字符串现在也有一个特殊字符$。如果您想$在替换文本中包含文字,也必须对此进行转义!

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

(Four $s because that is itself a replacement string—argh!)

(四个$s 因为它本身就是一个替换字符串——啊!)

Now you can implement global string replacement with RegExp:

现在您可以使用 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);
}

What a pain. Luckily if all you want to do is a straight string replace with no additional parts of regex, there is a quicker way:

多么痛苦。幸运的是,如果您想要做的只是一个直字符串替换而没有正则表达式的附加部分,那么有一个更快的方法:

s.split(string_to_replace).join(replacement)

...and that's all. This is a commonly-understood idiom.

...就这样。这是一个普遍理解的习语。

say I want to replace everything but string_to_replace

说我想替换除 string_to_replace 之外的所有内容

What does that mean, you want to replace all stretches of text not taking part in a match against the string? A replacement with ^certainly doesn't this, because ^means a start-of-string token, not a negation. ^is only a negation in []character groups. There are also negative lookaheads (?!...), but there are problems with that in JScript so you should generally avoid it.

这是什么意思,您想替换所有不参与与字符串匹配的文本?替换^当然不是这个,因为^意味着字符串开始标记,而不是否定。^只是[]字符组中的否定。也有负面的前瞻(?!...),但在 JScript 中存在问题,因此您通常应该避免它。

You might try matching ‘everything up to' the string, and using a function to discard any empty stretch between matching strings:

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

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

Here, again, a split might be simpler:

在这里,再次,拆分可能更简单:

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

回答by Kent

As the others have said, use new RegExp(pattern, flags)to do this. It is worth noting that you will be passing string literals into this constructor, so every backslash will have to be escaped. If, for instance you wanted your regex to match a backslash, you would need to say new RegExp('\\\\'), whereas the regex literal would only need to be /\\/. Depending on how you intend to use this, you should be wary of passing user input to such a function without adequate preprocessing (escaping special characters, etc.) Without this, your users may get some very unexpected results.

正如其他人所说,使用new RegExp(pattern, flags)这样做。值得注意的是,您将向此构造函数传递字符串文字,因此必须对每个反斜杠进行转义。例如,如果您希望正则表达式匹配反斜杠,则需要说new RegExp('\\\\'),而正则表达式文字只需要是/\\/. 根据您打算如何使用它,您应该警惕将用户输入传递给这样的函数而没有进行足够的预处理(转义特殊字符等)。否则,您的用户可能会得到一些非常意外的结果。

回答by Kristof Neirynck

Yes you can.

是的你可以。

https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions

https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions

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

回答by Zhurov Konstantin

I think I have very good example for highlight text in string (it finds not looking at register but highlighted using register)

我想我有很好的例子来突出显示字符串中的文本(它发现不是在看寄存器而是使用寄存器突出显示)

function getHighlightedText(basicString, filterString) {

    if ((basicString === "") || (basicString === null) || (filterString === "") || (filterString === null)) return basicString;

    return basicString.replace(new RegExp(filterString.replace(/[-\/\^$*+?.()|[\]{}]/g, '\\$&'), 'gi'),
        function(match)
            {return "<mark>"+match+"</mark>"});

}

http://jsfiddle.net/cdbzL/1258/

http://jsfiddle.net/cdbzL/1258/

回答by Hyman Allan

A really simple solution to this is this:

一个非常简单的解决方案是这样的:

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

No need for Regexes at all

根本不需要正则表达式

It also seems to be the fastest on modern browsers https://jsperf.com/replace-vs-split-join-vs-replaceall

它似乎也是现代浏览器上最快的https://jsperf.com/replace-vs-split-join-vs-replaceall