题 如何在正则表达式中使用变量?


我想在JavaScript中创建一个String.replaceAll()方法,我认为使用RegEx将是最简洁的方法。但是,我无法弄清楚如何将变量传递给RegEx。我已经可以做到这一点,它将用“A”替换所有“B”的实例。

"ABABAB".replace(/B/g, "A");

但我想做这样的事情:

String.prototype.replaceAll = function(replaceThis, withThis) {
    this.replace(/replaceThis/g, withThis);
};

但显然这只会替换文本“replaceThis”...所以如何将此变量传递给我的RegEx字符串?


984
2018-01-30 00:11


起源


请注意,我们目前正在 致力于将此功能添加到JavaScript 如果您对此有意见,请加入讨论。 - Benjamin Gruenbaum


答案:


而不是使用 /regex/g 语法,你可以构造一个新的 正则表达式 目的:

var replace = "regex";
var re = new RegExp(replace,"g");

您可以通过这种方式动态创建正则表达式对象。然后你会做:

"mystring".replace(re, "newstring");

1384
2018-01-30 00:15



如果你需要使用像这样的表达式 /\/word\:\w*$/,一定要逃避你的反斜杠: new RegExp( '\\/word\\:\\w*$' )。 - Jonathan Swinney
完全逃脱说明: stackoverflow.com/a/6969486/151312 - CoolAJ86
问题表明RegEx仅用于进行常量字符串替换。所以这是答案是错误的,因为如果字符串包含RegEx元字符,它将失败。可悲的是,它被评为如此之高,会让人头疼... - dronus
传递变量的一个例子就是一个很好的答案。读完之后我还在苦苦挣扎。 - Goose
@JonathanSwinney: / 如果你从字符串构造正则表达式没有特殊意义,所以你不需要转义它。 /\/word\:\w*$/ 应该 new RegExp('/word\\:\\w*$') - Dávid Horváth


正如Eric Wendelin所说,你可以这样做:

str1 = "pattern"
var re = new RegExp(str1, "g");
"pattern matching .".replace(re, "regex");

这会产生 "regex matching ."。但是,如果str1是,它将失败 "."。你期望结果 "pattern matching regex",用。取代 "regex",但事实证明......

regexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregex

这是因为,虽然 "." 是一个String,在RegExp构造函数中它仍被解释为正则表达式,意味着任何非换行符,表示字符串中的每个字符。为此,以下功能可能有用:

 RegExp.quote = function(str) {
     return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
 };

然后你可以这样做:

str1 = "."
var re = new RegExp(RegExp.quote(str1), "g");
"pattern matching .".replace(re, "regex");

生产 "pattern matching regex"


167
2018-01-30 01:02



您知道要替换的第一个参数可以是普通字符串而不必是正则表达式吗? str1 =“。”; alert(“模式匹配。”。replace(str1,“string”)); - some
@some:当然。那是因为上面的例子是微不足道的。当您需要搜索或替换与常规字符串结合的模式时,请执行str.match(例如新的RegExp(“https?://”+ RegExp.escape(myDomainName))。令人讨厌的是,转义函数是没有内置。 - Gracenotes
(续)另外,明显的JC Grubbs需要全球替代;使用String.replace(String,String)实现全局替换对于大输入可能很慢。我只是说,前两个解决方案都是错误的,并且在某些输入上会出现意外故障。 - Gracenotes
developer.mozilla.org/en-US/docs/JavaScript/Guide/... 提供类似的功能,但他们排除 -,并包括 =!:/。 - chbrown
正确的术语是“逃避”,而不是“引用”。只是BTW。 - Lawrence Dol


"ABABAB".replace(/B/g, "A");

一如既往:除非必须,否则不要使用正则表达式。对于简单的字符串替换,成语是:

'ABABAB'.split('B').join('A')

那么你不必担心Gracenotes答案中提到的引用问题。


83
2018-02-01 03:43



很酷的想法,不会想到这样做! - devios1
你有没有测量过这比正则表达更快? - Mitar
这似乎更可取,特别是当需要匹配特殊的正则表达式字符,如'。' - Krease
嗯...不分裂也会使用RegExp;如果是这样,它不会导致同样的问题吗?无论如何... .split()。join()在某些平台上可能会更慢,因为它是两个操作,而.replace()是一个操作并且可以进行优化。
@ PacMan--:两个 split 和 replace 可以采取字符串或 RegExp 目的。那个问题 replace 有这个 split 不是当你使用一个字符串时,你只能获得一个替换。 - bobince


对于任何想要使用变量的人 比赛 方法,这对我有用

var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight

27
2017-11-28 15:32





这个:

var txt=new RegExp(pattern,attributes);

相当于:

var txt=/pattern/attributes;

看到 http://www.w3schools.com/jsref/jsref_obj_regexp.asp


21
2018-01-30 00:19



是的,但在第一个例子中它使用 pattern 作为变量,在第2个作为字符串 - vladkras


this.replace( new RegExp( replaceThis, 'g' ), withThis );

14
2018-01-30 00:16





String.prototype.replaceAll = function (replaceThis, withThis) {
   var re = new RegExp(replaceThis,"g"); 
   return this.replace(re, withThis);
};
var aa = "abab54..aba".replaceAll("\\.", "v");

用此测试 工具 


9
2018-02-01 09:14





你想动态地构建正则表达式,为此正确的解决方案是使用 new RegExp(string) 构造函数。为了使构造函数能够处理特殊字符 按照字面,你必须逃避它们。有一个内置功能 jQuery UI自动完成小部件 叫 $.ui.autocomplete.escapeRegex

[...]你可以使用内置的    $.ui.autocomplete.escapeRegex 功能。它需要一个字符串   参数和转义所有正则表达式字符,使结果安全   传递给 new RegExp()

如果您使用的是jQuery UI,则可以使用该功能,或复制其定义 来自消息来源

function escapeRegex(value) {
    return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
}

并像这样使用它:

"[z-a][z-a][z-a]".replace(new RegExp(escapeRegex("[z-a]"), "g"), "[a-z]");
//            escapeRegex("[z-a]")       -> "\[z\-a\]"
// new RegExp(escapeRegex("[z-a]"), "g") -> /\[z\-a\]/g
// end result                            -> "[a-z][a-z][a-z]"

7
2017-09-14 19:55





如果你想得到所有的事件(g),不区分大小写(i),并使用边界,使其不是另一个单词中的单词(\\b):

re = new RegExp(`\\b${replaceThis}\\b`, 'gi');

例:

let inputString = "I'm John, or johnny, but I prefer john.";
let replaceThis = "John";
let re = new RegExp(`\\b${replaceThis}\\b`, 'gi');
console.log(inputString.replace(re, "Jack")); // I'm Jack, or johnny, but I prefer Jack.

4
2018-06-13 02:52





虽然你可以制作动态创建的RegExp(根据对这个问题的其他回答),但我会回应我的评论。 类似的帖子:功能形式 与string.replace() 非常有用,在许多情况下减少了对动态创建的RegExp对象的需求。 (这是一种痛苦'因为你必须将RegExp构造函数的输入表示为字符串而不是使用斜杠/ [A-Z] + / regexp文字格式)


3
2018-01-30 01:02