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

时间:2009-01-30 00:11:05

标签: javascript regex

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

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

但我想做这样的事情:

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

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

23 个答案:

答案 0 :(得分:1590)

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

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

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

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

答案 1 :(得分:185)

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

答案 2 :(得分:98)

  

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

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

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

然后您不必担心Gracenotes答案中提到的引用问题。

答案 3 :(得分:32)

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

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

答案 4 :(得分:27)

此:

var txt=new RegExp(pattern,attributes);

相当于:

var txt=/pattern/attributes;

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

答案 5 :(得分:18)

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

答案 6 :(得分:17)

如果要获取所有出现次数(var person = {}, people = []; function add(){ person.name = document.getElementById('name').value; person.lastname = document.getElementById('lname').value; people.push(person); console.table(people); } ),请不区分大小写(g),并使用边界使其不是另一个单词中的单词(i) :

\\b

示例:

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

答案 7 :(得分:9)

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

使用此tool

进行测试

答案 8 :(得分:9)

您希望动态构建正则表达式,为此,正确的解决方案是使用new RegExp(string)构造函数。为了让构造函数处理特殊字符字面,您必须将它们转义。 jQuery UI autocomplete widget中有一个名为$.ui.autocomplete.escapeRegex的内置函数:

  

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

如果您使用的是jQuery UI,则可以使用该功能,或复制其定义from the source

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 :(得分: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("]", ">"))

答案 10 :(得分: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;
    };

答案 11 :(得分:3)

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

示例:

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

答案 12 :(得分:3)

Steven Penny的coffeescript版本的答案,因为这是#2 google结果....即使咖啡只是javascript,删除了很多字符......;)

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

答案 13 :(得分: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");

其中&#39; oldre&#39;是我要插入变量的原始正则表达式, &#39; XX&#39;是该变量/别名/函数的占位符, 并且&#39; yy&#39;是实际的变量名,别名或函数。

答案 14 :(得分:3)

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

答案 15 :(得分: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);
};

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

答案 16 :(得分:1)

如果$ 1无法与您合作,您可以使用此

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

答案 17 :(得分:1)

您的解决方案就在这里:

Pass a variable to regular expression.

我实现的是通过从要替换的文本字段中获取值,另一个是“替换为”文本字段,从变量中的text-field获取值并设置变量到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事件上,您可以将其置于要调用的函数中。

所以现在你可以在替换函数中传递变量。

答案 18 :(得分:1)

这些答案对我来说都不是很清楚。我最终在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>

答案 19 :(得分: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

The important part of the solution was found here

答案 20 :(得分:0)

此自调用函数将使用索引遍历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'

答案 21 :(得分:0)

作为 JavaScript 新手,已接受的答案 https://stackoverflow.com/a/494046/1904943 被注意到/赞赏,但它不是很直观。

这是一个更简单的解释,例如(使用 simple JavaScript IDE)。

myString = 'apple pie, banana loaf';

console.log(myString.replaceAll(/pie/gi, 'PIE'))
// apple PIE, banana loaf

console.log(myString.replaceAll(/\bpie\b/gi, 'PIE'))
// apple PIE, banana loaf

console.log(myString.replaceAll(/pi/gi, 'PIE'))
// apple PIEe, banana loaf

console.log(myString.replaceAll(/\bpi\b/gi, 'PIE'))
// [NO EFFECT] apple pie, banana loaf

const match_word = 'pie';

console.log(myString.replaceAll(/match_word/gi, '**PIE**'))
// [NO EFFECT] apple pie, banana loaf

console.log(myString.replaceAll(/\b`${bmatch_word}`\b/gi, '**PIE**'))
// [NO EFFECT] apple pie, banana loaf

// ----------------------------------------
// ... new RegExp(): be sure to \-escape your backslashes: \b >> \\b ...

const match_term = 'pie';
const match_re = new RegExp(`(\\b${match_term}\\b)`, 'gi')

console.log(myString.replaceAll(match_re, 'PiE'))
// apple PiE, banana loaf

console.log(myString.replace(match_re, '**PIE**'))
// apple **PIE**, banana loaf

console.log(myString.replaceAll(match_re, '**PIE**'))
// apple **PIE**, banana loaf

申请

例如:替换(颜色突出显示)字符串/句子中的单词,[可选] 如果搜索词匹配超过用户定义的匹配单词比例。

注意:保留匹配项的原始字符大小写。 hl:突出显示; re:正则表达式 |正则表达式

mySentence = "Apple, boOk? BOoks; booKEd. BookMark, 'BookmarkeD', bOOkmarks! bookmakinG, Banana; bE, BeEn, beFore."

function replacer(mySentence, hl_term, hl_re) {
    console.log('mySentence [raw]:', mySentence)
    console.log('hl_term:', hl_term, '| hl_term.length:', hl_term.length)
    cutoff = hl_term.length;
    console.log('cutoff:', cutoff)

    // `.match()` conveniently collects multiple matched items
    // (including partial matches) into an [array]
    const hl_terms  = mySentence.toLowerCase().match(hl_re, hl_term);
    if (hl_terms == null) {
        console.log('No matches to hl_term "' + hl_term + '"; echoing input string then exiting ...')
        return mySentence;
    }
    console.log('hl_terms:', hl_terms)
    for (let i = 0;  i < hl_terms.length; i++) {
        console.log('----------------------------------------')
        console.log('[' + i + ']:', hl_terms[i], '| length:', hl_terms[i].length, '| parseInt(0.7(length)):', parseInt(0.7*hl_terms[i].length))
        // TEST: if (hl_terms[i].length >= cutoff*10) {
        if (cutoff >= parseInt(0.7 * hl_terms[i].length)) {
            var match_term = hl_terms[i].toString();

            console.log('matched term:', match_term, '[cutoff length:', cutoff, '| 0.7(matched term length):', parseInt(0.7 * hl_terms[i].length))

            const match_re = new RegExp(`(\\b${match_term}\\b)`, 'gi')

            mySentence = mySentence.replaceAll(match_re, '<font style="background:#ffe74e">$1</font>');
        }
        else {
            var match_term = hl_terms[i].toString();
            console.log('NO match:', match_term, '[cutoff length:', cutoff, '| 0.7(matched term length):', parseInt(0.7 * hl_terms[i].length))
        }
    }
    return mySentence;
}

// TESTS:
// const hl_term = 'be';
// const hl_term = 'bee';
// const hl_term = 'before';
// const hl_term = 'book';
const hl_term = 'bookma';
// const hl_term = 'Leibniz';

// This regex matches from start of word:
const hl_re = new RegExp(`(\\b${hl_term}[A-z]*)\\b`, 'gi')

mySentence = replacer(mySentence, hl_term, hl_re);
console.log('mySentence [processed]:', mySentence)

输出

mySentence [raw]: Apple, boOk? BOoks; booKEd. BookMark, 'BookmarkeD',
bOOkmarks! bookmakinG, Banana; bE, BeEn, beFore.

hl_term: bookma | hl_term.length: 6
cutoff: 6
hl_terms: Array(4) [ "bookmark", "bookmarked", "bookmarks", "bookmaking" ]

----------------------------------------
[0]: bookmark | length: 8 | parseInt(0.7(length)): 5
matched term: bookmark [cutoff length: 6 | 0.7(matched term length): 5
----------------------------------------
[1]: bookmarked | length: 10 | parseInt(0.7(length)): 7
NO match: bookmarked [cutoff length: 6 | 0.7(matched term length): 7
----------------------------------------
[2]: bookmarks | length: 9 | parseInt(0.7(length)): 6
matched term: bookmarks [cutoff length: 6 | 0.7(matched term length): 6
----------------------------------------
[3]: bookmaking | length: 10 | parseInt(0.7(length)): 7
NO match: bookmaking [cutoff length: 6 | 0.7(matched term length): 7

mySentence [processed]: Apple, boOk? BOoks; booKEd.
<font style="background:#ffe74e">BookMark</font>, 'BookmarkeD',
<font style="background:#ffe74e">bOOkmarks</font>! bookmakinG,
Banana; bE, BeEn, beFore.

答案 22 :(得分:0)

如果您使用正确的语法传递变量,则可以使用以下代码执行此操作。

这具有在同一变量中使用标志的额外好处。

此外,当涉及到 \ 等时,您不必在正则表达式中重复转义 \w

var str = 'regexVariable example: This is my example of RegExp replacing with a regexVariable.'
var reVar = /(.*?)(regex\w+?iable)(.+?)/gi;
var resStr = str.replace(new RegExp(reVar), '$1 :) :) :) $2 :) :) :)$3');
console.log(resStr);

// Returns:
// :) :) :) regexVariable :) :) :) example: This is my example of RegExp replacing with a  :) :) :) regexVariable :) :) :).

根据 OP 示例的原型版本:

var str = 'regexVariable prototype: This is my example of RegExp replacing with a regexVariable.'

String.prototype.regexVariable = function(reFind, reReplace) {
return str.replace(new RegExp(reFind), reReplace);
}

var reVar = /(.*?)(regex\w+?iable)(.+?)/gi;

console.log(str.regexVariable(reVar, '$1 :) :) :) $2 :) :) :)$3'));

// Returns:
// :) :) :) regexVariable :) :) :) prototype: This is my example of replacing with a  :) :) :) regexVariable :) :) :).