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


1377

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

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

但是我想做这样的事情:

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

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


9
请注意,如果您对此功能有意见,我们目前正在努力将该功能添加到JavaScript中,请加入讨论。
本杰明·格伦鲍姆

Answers:


1838

代替使用/regex/g语法,可以构造一个新的RegExp对象:

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

您可以通过这种方式动态创建正则表达式对象。然后,您将执行以下操作:

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

272
如果您需要使用类似这样的表达式/\/word\:\w*$/,请务必转义反斜杠:new RegExp( '\\/word\\:\\w*$' )
乔纳森·斯威尼

2
@gravityboy您可以执行(''+ myNumber).replace(/ 10 / g,'a'),或者如果您想要十六进制数,则可以执行parseInt(''+ myNumber,16)从十进制转换为十六进制。
Eric Wendelin

29
该问题表明RegEx仅用于进行常量字符串替换。所以这是错误的答案,因为如果字符串包含RegEx元字符,它将失败。伤心的是,它被投票定为如此之高,将使许多人头疼...
dronus 2014年

16
传递变量的示例将是一个很好的答案。阅读这篇文章后,我仍然在努力。
鹅2015年

3
@JonathanSwinney:/如果您从字符串构造正则表达式,则没有特殊含义,因此您无需对其进行转义。/\/word\:\w*$/应该是new RegExp('/word\\:\\w*$')
大卫·霍瓦特

211

正如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"


4
您知道要替换的第一个参数可以是普通字符串,而不必是正则表达式吗?str1 =“。”; alert(“ pattern matching。”。replace(str1,“ string”));
一些

@some:当然。那是因为上面的例子很简单。例如,当您需要搜索或替换与常规字符串组合的模式时,请执行str.match(new RegExp(“ https?://” + RegExp.escape(myDomainName)))。没有内置的。
Gracenotes

(续)另外,显然JC Grubbs需要进行全球更换。对于大型输入,使用String.replace(String,String)实现全局替换可能会很慢。我只是说,前两个解决方案是错误的,并且在某些输入上会意外失败。
Gracenotes,

4
developer.mozilla.org/zh-CN/docs/JavaScript/Guide/…提供了类似的功能,但它们排除了-,包括=!:/
chbrown

8
正确的术语是“转义”,而不是“引号”。顺便说一句。
劳伦斯·多尔

118

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

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

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

然后,您不必担心Gracenotes答案中提到的报价问题。


11
您是否测量过它比正则表达式快?
Mitar

3
这似乎是可取的,特别是当需要匹配特殊的正则表达式字符(如“。”)时。
Krease

1
嗯...不拆分也要使用RegExp;如果是这样,会不会引起同样的问题?无论如何... .split()。join()在某些平台上可能会比较慢,因为它是两个操作,而.replace()是一个操作并且可以进行优化。

5
@ PacMan--:既splitreplace可以采取一个字符串或一个RegExp对象。这个问题replacesplit没有是,当你使用一个字符串,你只能得到一个替代品。
bobince 2013年


38

如果您希望获得所有出现(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 / -style插值明确给出的答案。)
sam boosalis

34

对于希望将变量与match方法一起使用的任何人,这对我来说都很有效

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


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

我喜欢这个答案,因为它不会创建多余的(无意义的)变量。
威克

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]"

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

用这个工具测试


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

像这样测试:

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

console.log(whatever.replaceAll("[", "<").replaceAll("]", ">"))

4

这是另一个replaceAll实现:

    String.prototype.replaceAll = function (stringToFind, stringToReplace) {
        if ( stringToFind == stringToReplace) return this;
        var temp = this;
        var index = temp.indexOf(stringToFind);
        while (index != -1) {
            temp = temp.replace(stringToFind, stringToReplace);
            index = temp.indexOf(stringToFind);
        }
        return temp;
    };

4

还有史蒂文·彭尼(Steven Penny)答案的coffeescript版本,因为这是Google排名第二的结果。

baz = "foo"
filter = new RegExp(baz + "d")
"food fight".match(filter)[0] // food

在我的情况下

robot.name=hubot
filter = new RegExp(robot.name)
if msg.match.input.match(filter)
  console.log "True!"

为什么要投票?coffeescript -IS- javascript及其自身的特定语法。
敏锐,

robot.name=hubot不是javascript。
codepleb

3

尽管您可以制作动态创建的RegExp(根据对此问题的其他回答),但我会在类似的帖子中回应我的评论:String.replace()的功能形式非常有用,并且在许多情况下减少了对动态创建的RegExp对象。(这很麻烦,因为您必须将RegExp构造函数的输入表示为字符串,而不是使用斜杠/ [AZ] + / regexp文字格式)


3

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

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

String.prototype.replaceAll = this.replace(newre(oldre), "withThis");

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


2

如果$ 1不起作用,则可以使用此功能

var pattern = new RegExp("amman","i");
"abc Amman efg".replace(pattern,"<b>"+"abc Amman efg".match(pattern)[0]+"</b>");

1

您可以随时indexOf重复使用:

String.prototype.replaceAll = function(substring, replacement) {
    var result = '';
    var lastIndex = 0;

    while(true) {
        var index = this.indexOf(substring, lastIndex);
        if(index === -1) break;
        result += this.substring(lastIndex, index) + replacement;
        lastIndex = index + substring.length;
    }

    return result + this.substring(lastIndex);
};

当替换包含匹配项时,这不会陷入无限循环。


1

您的解决方案在这里:

将变量传递给正则表达式。

我实现的一个方法是从一个文本字段中获取值,该文本字段是您要替换的值,另一个是“替换为”文本字段,从一个变量的文本字段中获取值,并将该变量设置为RegExp功能进一步取代。就我而言,我使用的是Jquery,您也可以仅通过JavaScript来实现。

JavaScript代码:

  var replace =document.getElementById("replace}"); // getting a value from a text field with I want to replace
  var replace_with = document.getElementById("with"); //Getting the value from another text fields with which I want to replace another string.

  var sRegExInput = new RegExp(replace, "g");    
  $("body").children().each(function() {
    $(this).html($(this).html().replace(sRegExInput,replace_with));
  });

此代码位于按钮的Onclick事件上,您可以将其放入函数中进行调用。

因此,现在您可以在replace函数中传递变量。


您的replace_with变量将包含DOM元素,而不包含值本身
Ben Taliadoros

1

此自调用函数将使用索引遍历replacerItems,并在每次传递时在字符串上全局更改replacerItems [index]。

  const replacerItems = ["a", "b", "c"];    

    function replacer(str, index){
          const item = replacerItems[index];
          const regex = new RegExp(`[${item}]`, "g");
          const newStr = str.replace(regex, "z");
          if (index < replacerItems.length - 1) {
            return replacer(newStr, index + 1);
          }
          return newStr;
    }

// console.log(replacer('abcdefg', 0)) will output 'zzzdefg'

0

这些答案我都不清楚。我最终在http://burnignorance.com/php-programming-tips/how-to-use-a-variable-in-replace-function-of-javascript/找到了很好的解释

简单的答案是:

var search_term = new RegExp(search_term, "g");    
text = text.replace(search_term, replace_term);

例如:

$("button").click(function() {
  Find_and_replace("Lorem", "Chocolate");
  Find_and_replace("ipsum", "ice-cream");
});

function Find_and_replace(search_term, replace_term) {
  text = $("textbox").html();
  var search_term = new RegExp(search_term, "g");
  text = text.replace(search_term, replace_term);
  $("textbox").html(text);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textbox>
  Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum
</textbox>
<button>Click me</button>


1
您正在覆盖闭包变量,无需在var此处使用。另外,如果您通过\b\1将破裂。
Cyber​​AP

0

对于没有正则表达式的多次替换,我进行了以下操作:

      let str = "I am a cat man. I like cats";
      let find = "cat";
      let replace = "dog";


      // Count how many occurrences there are of the string to find 
      // inside the str to be examined.
      let findCount = str.split(find).length - 1;

      let loopCount = 0;

      while (loopCount < findCount) 
      {
        str = str.replace(find, replace);
        loopCount = loopCount + 1;
      }  

      console.log(str);
      // I am a dog man. I like dogs

解决方案的重要部分在这里找到

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.