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

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

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

我想做这样的事情:

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

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

1147147 次浏览

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

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

您可以通过这种方式动态创建regex对象。然后您将执行:

"mystring1".replace(re, "newstring");
this.replace( new RegExp( replaceThis, 'g' ), withThis );

这个:

var txt=new RegExp(pattern,attributes);

相当于这样:

var txt=/pattern/attributes;

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

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

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

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

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

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

那么你就不必担心Gracenote回答中提到的引用问题了。

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

用这个测试工具

对于任何想要使用匹配方法的变量的人来说,这对我很有效:

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

这是另一个replace All实现:

    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;};

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

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'是实际的变量名、别名或函数。

如果$1不适合你,你可以使用它:

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

你总是可以重复使用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);};

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

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

您需要动态构建正则表达式并为此您必须使用#0构造函数进行转义

jQuery UI自动完成小部件中有一个名为$.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]"

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

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

在我的特殊情况下:

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

一种实现方法是从文本字段中获取值,这是您要替换的文本字段,另一种是“替换为”文本字段,从变量中的文本字段获取值并将变量设置为RegExp函数以进一步替换。在我的情况下,我使用jQuery,但您也可以仅通过JavaScript来完成。

JavaScript代码:

  var replace =document.getElementById("replace}"); // getting a value from a text field with I want to replacevar 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事件上,您可以将其放在要调用的函数中。

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

如果你想得到所有次出现(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"));

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

对于没有正则表达式的多个替换,我采用了以下方法:

      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

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

这个自调用函数将使用索引遍历replace erItems,并在每次遍历时全局更改字符串上的replace erItems[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'

作为一个相对的JavaScript新手,接受的答案https://stackoverflow.com/a/494046/1904943是值得注意/赞赏的,但它不是很直观。

这是一个简单的解释,通过示例(使用简单的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: 6cutoff: 6hl_terms: Array(4) [ "bookmark", "bookmarked", "bookmarks", "bookmaking" ]
----------------------------------------[0]: bookmark | length: 8 | parseInt(0.7(length)): 5matched term: bookmark [cutoff length: 6 | 0.7(matched term length): 5----------------------------------------[1]: bookmarked | length: 10 | parseInt(0.7(length)): 7NO match: bookmarked [cutoff length: 6 | 0.7(matched term length): 7----------------------------------------[2]: bookmarks | length: 9 | parseInt(0.7(length)): 6matched term: bookmarks [cutoff length: 6 | 0.7(matched term length): 6----------------------------------------[3]: bookmaking | length: 10 | parseInt(0.7(length)): 7NO 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.

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

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

此外,当涉及到\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 :) :) :).

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

示例:

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

示例:regex start with

function startWith(char, value) {return new RegExp(`^[${char}]`, 'gi').test(value);}

我在这里和stackoverflow或类似论坛上的其他开放门票中找到了很多奇怪的例子。

在我看来,这是最简单的选择,你可以把变量作为模板文字字符串;

const someString = "abc";const regex = new RegExp(`^ someregex ${someString} someregex $`);

正如你所看到的,我没有在开头或结尾推入正斜杠,RegExp构造函数将重建有效的正则表达式文字。也适用于yup匹配函数。

所有这些答案看起来都非常复杂,当有一个更简单的答案仍然可以使用regex完成工作时。

String.prototype.replaceAll = function(replaceThis, withThis) {const expr = `${replaceThis}`this.replace(new RegExp(expr, "g"), withThis);};

补充说明

RegExp构造函数接受2个参数:表达式和标志。通过在表达式中使用模板字符串,我们可以将变量传入类,并将其转换为/(value of the replaceThis variable)/g