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

JC *_*bbs 1250 javascript regex

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

"ABABAB".replace(/B/g, "A");
Run Code Online (Sandbox Code Playgroud)

但我想做这样的事情:

String.prototype.replaceAll = function(replaceThis, withThis) {
    this.replace(/replaceThis/g, withThis);
};
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*lin 1709

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

var replace = "regex";
var re = new RegExp(replace,"g");
Run Code Online (Sandbox Code Playgroud)

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

"mystring".replace(re, "newstring");
Run Code Online (Sandbox Code Playgroud)

  • 如果你需要使用像`/\/ word \:\ w*$ /`这样的表达式,请务必使用反斜杠:`new RegExp('\\/word \\:\\ w*$')`. (251认同)
  • 问题表明RegEx仅用于进行常量字符串替换.所以这是答案是错误的,因为如果字符串包含RegEx元字符,它将失败.可悲的是,它投得如此之高,会让人头疼...... (24认同)
  • 传递变量的一个例子就是一个很好的答案.读完之后我还在苦苦挣扎. (14认同)
  • @JonathanSwinney:`/`如果你从string构造正则表达式没有特殊意义,所以你不需要转义它.`/\/ word \:\ w*$ /`应该是`new RegExp('/ word \\:\\ w*$')` (3认同)
  • @gravityboy你可以做(​​''+ myNumber).replace(/ 10/g,'a')或者你想要十六进制数字,你可以做parseInt(''+ myNumber,16)从十进制转换为十六进制. (2认同)

Gra*_*tes 200

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

str1 = "pattern"
var re = new RegExp(str1, "g");
"pattern matching .".replace(re, "regex");
Run Code Online (Sandbox Code Playgroud)

这产生了"regex matching .".但是,如果str1是,它将失败".".你期望得到的结果"pattern matching regex",取代期间"regex",但结果是......

regexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregex
Run Code Online (Sandbox Code Playgroud)

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

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

然后你可以这样做:

str1 = "."
var re = new RegExp(RegExp.quote(str1), "g");
"pattern matching .".replace(re, "regex");
Run Code Online (Sandbox Code Playgroud)

屈服"pattern matching regex".

  • 正确的术语是"逃避",而不是"引用".只是BTW. (6认同)
  • 您知道要替换的第一个参数可以是普通字符串而不必是正则表达式吗?str1 ="."; alert("模式匹配.".replace(str1,"string")); (4认同)
  • https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions提供了类似的功能,但它们排除了`-`,并包含`=!:/`. (4认同)

bob*_*nce 110

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

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

'ABABAB'.split('B').join('A')
Run Code Online (Sandbox Code Playgroud)

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

  • 你有没有测量过这比正则表达更快? (10认同)
  • @ PacMan--:`split`和`replace`都可以使用字符串或`RegExp`对象.`replace`的问题是`split`不是因为当你使用一个字符串时,你只能获得一个替换. (5认同)
  • 这似乎更可取,特别是当需要匹配特殊的正则表达式字符,如'.' (3认同)
  • 嗯...不拆分也采用正则表达式;如果是这样,那不会导致同样的问题吗?无论如何... .split().join() 在某些平台上可能会更慢,因为它是两个操作,而 .replace() 是一个操作并且可以进行优化。 (2认同)
  • 这里的基准测试:https://jsperf.com/replace-vs-split-join-vs-replaceall/23 (2认同)
  • “否则它们没有明显的好处”您不认为让您的代码几乎不可读是一种好处吗? (2认同)

小智 32

对于任何希望使用匹配方法使用变量的人来说,这对我有用

var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight
Run Code Online (Sandbox Code Playgroud)


Jer*_*ten 30

这个:

var txt=new RegExp(pattern,attributes);
Run Code Online (Sandbox Code Playgroud)

相当于:

var txt=/pattern/attributes;
Run Code Online (Sandbox Code Playgroud)

请参见http://www.w3schools.com/jsref/jsref_obj_regexp.asp.

  • 是的,但在第一个例子中,它使用`pattern`作为变量,在2nd中作为字符串 (18认同)

JBa*_*lin 26

如果你想获得ALL occurrence(g),不区分大小写(i),并使用边界,使它不是另一个单词(\\b)中的单词:

re = new RegExp(`\\b${replaceThis}\\b`, 'gi');
Run Code Online (Sandbox Code Playgroud)

例:

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.
Run Code Online (Sandbox Code Playgroud)


tva*_*son 18

this.replace( new RegExp( replaceThis, 'g' ), withThis );
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个答案,因为它不会创建额外的(且无意义的)变量。 (2认同)

Sal*_*n A 13

您想要动态构建正则表达式,为此,正确的解决方案是使用new RegExp(string)构造函数.为了让构造函数按字面意思处理特殊字符,您必须将它们转义.在jQuery UI自动完成小部件中有一个内置函数,名为$.ui.autocomplete.escapeRegex:

[...]您可以使用内置 $.ui.autocomplete.escapeRegex功能.它将采用单个字符串参数并转义所有正则表达式字符,使结果安全传递给new RegExp().

如果您使用的是jQuery UI,则可以使用该函数,或者从源代码复制其定义:

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

并像这样使用它:

"[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]"
Run Code Online (Sandbox Code Playgroud)


uni*_*ogo 9

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

使用此工具进行测试


Ale*_* Li 5

为了满足我将变量/别名/函数插入正则表达式的需要,这就是我想出的:

oldre = /xx\(""\)/;
function newre(e){
    return RegExp(e.toString().replace(/\//g,"").replace(/xx/g, yy), "g")
};

String.prototype.replaceAll = this.replace(newre(oldre), "withThis");
Run Code Online (Sandbox Code Playgroud)

其中“oldre”是我要插入变量的原始正则表达式,“xx”是该变量/别名/函数的占位符,“yy”是实际的变量名称、别名或函数。


Met*_*win 5

String.prototype.replaceAll = function(a, b) {
    return this.replace(new RegExp(a.replace(/([.?*+^$[\]\\(){}|-])/ig, "\\$1"), 'ig'), b)
}
Run Code Online (Sandbox Code Playgroud)

测试它像:

var whatever = 'Some [b]random[/b] text in a [b]sentence.[/b]'

console.log(whatever.replaceAll("[", "<").replaceAll("]", ">"))
Run Code Online (Sandbox Code Playgroud)


kee*_*een 5

以及Steven Penny 的答案的 CoffeeScript 版本,因为这是 #2 Google 结果......即使 CoffeeScript 只是删除了很多字符的 JavaScript......;)

baz = "foo"
filter = new RegExp(baz + "d")
"food fight".match(filter)[0] // food
Run Code Online (Sandbox Code Playgroud)

在我的特殊情况下:

robot.name = hubot
filter = new RegExp(robot.name)
if msg.match.input.match(filter)
  console.log "True!"
Run Code Online (Sandbox Code Playgroud)

  • `robot.name=hubot` 不是 JavaScript。 (3认同)

小智 5

您可以将字符串用作正则表达式。不要忘记使用new RegExp

例子:

var yourFunction = new RegExp(
        '^-?\\d+(?:\\.\\d{0,' + yourVar + '})?'
      )
Run Code Online (Sandbox Code Playgroud)