![](/img/trans.png)
[英]How do you use a variable in a regular expression and manipulate the variable?
[英]How do you use a variable in a regular expression?
我想在 JavaScript 中創建一個String.replaceAll()
方法,我認為使用正則表達式是最簡潔的方法。 但是,我不知道如何將變量傳遞給正則表達式。 我已經可以這樣做了,它將用"A"
替換"B"
的所有實例。
"ABABAB".replace(/B/g, "A");
但我想做這樣的事情:
String.prototype.replaceAll = function(replaceThis, withThis) {
this.replace(/replaceThis/g, withThis);
};
但顯然這只會替換文本"replaceThis"
......那么我如何將此變量傳遞給我的正則表達式字符串?
您可以構造一個新的RegExp對象,而不是使用/regex\\d/g
語法:
var replace = "regex\\d";
var re = new RegExp(replace,"g");
您可以通過這種方式動態創建正則表達式對象。 然后你會做:
"mystring1".replace(re, "newstring");
正如 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"
。
"ABABAB".replace(/B/g, "A");
與往常一樣:除非必須,否則不要使用正則表達式。 對於簡單的字符串替換,成語是:
'ABABAB'.split('B').join('A')
那么您不必擔心 Gracenotes 的回答中提到的引用問題。
如果你想獲得所有的出現( 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.
對於希望通過match方法使用變量的任何人,這對我有用:
var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight
這:
var txt=new RegExp(pattern,attributes);
相當於:
var txt=/pattern/attributes;
this.replace( new RegExp( replaceThis, 'g' ), withThis );
您需要動態構建正則表達式,為此您必須使用帶有 escaping 的new RegExp(string)
構造函數。
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]"
String.prototype.replaceAll = function (replaceThis, withThis) {
var re = new RegExp(replaceThis,"g");
return this.replace(re, withThis);
};
var aa = "abab54..aba".replaceAll("\\.", "v");
用這個工具測試
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("]", ">"))
還有Steven Penny 回答的 CoffeeScript 版本,因為這是 Google 結果的第 2 位……即使 CoffeeScript 只是刪除了很多字符的 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!"
為了滿足我將變量/別名/函數插入正則表達式的需要,這就是我想出的:
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”是實際的變量名稱、別名或函數。
您可以將字符串用作正則表達式。 不要忘記使用新的 RegExp 。
例子:
var yourFunction = new RegExp(
'^-?\\d+(?:\\.\\d{0,' + yourVar + '})?'
)
這是另一個 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;
};
如果$1
不適合您,您可以使用它:
var pattern = new RegExp("amman", "i");
"abc Amman efg".replace(pattern, "<b>" + "abc Amman efg".match(pattern)[0] + "</b>");
您的解決方案在這里:
我已經實現的一個是通過從文本字段中獲取值,這是您要替換的文本字段,另一個是“替換為”文本字段,從變量中的文本字段獲取值並將變量設置為 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 事件上,你可以把它放在一個函數中調用。
所以現在你可以在替換函數中傳遞一個變量。
雖然您可以動態創建正則表達式(根據對這個問題的其他回復),但我會從類似的帖子中回應我的評論: String.replace()的函數形式非常有用,在許多情況下減少了對動態創建的 RegExp 對象。 (這有點痛苦,因為您必須將 RegExp 構造函數的輸入表示為字符串,而不是使用斜杠 /[AZ]+/ regexp 文字格式)
這些答案對我來說都不清楚。 我最終在如何在 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>
這個自調用函數將使用索引迭代 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'
您總是可以重復使用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);
};
當替換包含匹配項時,這不會進入無限循環。
對於沒有正則表達式的多個替換,我使用以下內容:
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
作為一個相對的 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: 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.
如果您使用正確的語法傳遞變量,則可以使用下面的代碼執行此操作。
這具有在同一變量中使用標志的額外好處。
此外,當涉及\\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 :) :) :).
示例:正則表達式以
function startWith(char, value) {
return new RegExp(`^[${char}]`, 'gi').test(value);
}
我在這里和 stackoverflow 或類似論壇上的其他公開票證中找到了很多帶有奇怪示例的答案。
在我看來,這是最簡單的選擇,您可以將變量作為模板文字字符串;
const someString = "abc";
const regex = new RegExp(`^ someregex ${someString} someregex $`);
如您所見,我沒有在開頭或結尾提出斜杠,RegExp 構造函數將重建有效的正則表達式文字。 也適用於 yup 匹配 function。
當有一個更簡單的答案仍然可以使用正則表達式完成工作時,所有這些答案似乎都非常復雜。
String.prototype.replaceAll = function(replaceThis, withThis) {
const expr = `${replaceThis}`
this.replace(new RegExp(expr, "g"), withThis);
};
解釋
RegExp
構造函數采用 2 arguments:表達式和標志。 通過在表達式中使用模板字符串,我們可以將變量傳遞給 class,它會將其轉換為/(value of the replaceThis variable)/g
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.