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

IT技术 javascript regex
2020-12-27 00:43:31

我想String.replaceAll()在 JavaScript 中创建一个方法,我认为使用正则表达式是最简洁的方法。但是,我不知道如何将变量传递给正则表达式。我已经可以做到这一点,它将替换"B"with 的所有实例"A"

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

但我想做这样的事情:

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

但显然这只会替换文本"replaceThis"......那么我如何将此变量传递给我的正则表达式字符串?

6个回答

/regex\d/g您可以构造一个新的RegExp对象而不是使用语法

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

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

"mystring1".replace(re, "newstring");
@JonathanSwinney:/如果您从字符串构造正则表达式,则没有特殊含义,因此您无需对其进行转义。/\/word\:\w*$/应该new RegExp('/word\\:\\w*$')
2021-02-26 00:43:31
@gravityboy 你可以做 ('' + myNumber).replace(/10/g, 'a') 或者如果你想要十六进制数字,你可以做 parseInt('' + myNumber, 16) 从十进制转换为十六进制。
2021-03-01 00:43:31
传递变量的一个示例将使这成为一个很好的答案。读完之后我还在挣扎。
2021-03-04 00:43:31
如果您需要使用类似 的表达式/\/word\:\w*$/,请务必转义您的反斜杠:new RegExp( '\\/word\\:\\w*$' )
2021-03-05 00:43:31
该问题表明 RegEx 仅用于进行常量字符串替换。所以这个答案是错误的,因为如果字符串包含 RegEx 元字符,它会失败。可悲的是,投票如此之高,会让很多人头疼...
2021-03-08 00:43:31

正如 Eric Wendelin 所提到的,您可以执行以下操作:

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

这产生"regex matching .". 但是,如果 str1 是 ,它将失败"."您希望结果是"pattern matching regex",用 替换句点"regex",但结果是...

regexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregex

这是因为,虽然"."是一个字符串,但在 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"

您知道要替换的第一个参数可以是普通字符串而不必是正则表达式吗?str1 = "."; alert("模式匹配。".replace(str1, "string"));
2021-02-09 00:43:31
(续)另外,显然 JC Grubbs 需要全局替换;使用 String.replace(String, String) 实现全局替换对于大输入可能会很慢。我只是说,前两个解决方案有问题,并且会在某些输入上意外失败。
2021-02-10 00:43:31
正确的术语是“转义”,而不是“引用”。顺便说一句。
2021-02-21 00:43:31
@一些:当然。那是因为上面的例子是微不足道的。当你需要搜索或替换一个与正则字符串组合的模式时,例如执行str.match(new RegExp("https?://" + RegExp.escape(myDomainName))。转义函数很烦人没有内置。
2021-03-07 00:43:31
developer.mozilla.org/en-US/docs/JavaScript/Guide/...提供了类似的功能,但它们排除-,并包含=!:/
2021-03-08 00:43:31

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

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

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

那么您就不必担心 Gracenotes 的回答中提到的引用问题。

2021-02-09 00:43:31
你有没有测量过这比正则表达式快?
2021-02-24 00:43:31
这似乎更可取,尤其是当需要匹配特殊的正则表达式字符时,如 '.'
2021-02-24 00:43:31
嗯...也不会拆分使用正则表达式;如果是这样,它会不会导致同样的问题?无论如何... .split().join() 在某些平台上可能会更慢,因为它是两个操作,而 .replace() 是一个操作并且可能会被优化。
2021-02-24 00:43:31
@ PacMan--:既splitreplace可以采取一个字符串或一个RegExp对象。这个问题replacesplit没有是,当你使用一个字符串,你只能得到一个替代品。
2021-03-02 00:43:31

如果您想获取所有出现的 ( 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.
谢谢你!(事实上​​,你是rx通过模板字符串明确使用 Emacs/样式插值的唯一答案。)
2021-02-09 00:43:31
@cezar 从技术上讲,您可以使用replaceAll上面的确切正则表达式(包括全局标志) - 但它没有任何好处。如果您尝试在没有全局标志的情况下使用它,则会出现错误,请参阅
2021-02-14 00:43:31
怎么样replaceAll它会replace全局标志一样工作吗?
2021-03-07 00:43:31

对于希望在match方法中使用变量的任何人,这对我有用

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