2010-04-07 57 views
90

我有這樣的代碼:如何在javascript中逃避正則表達式?

pattern = 'arrayname[1]'; // fetch from dom, make literal here just for example 
reg = new RegExp(RegExp.quote(pattern), 'g'); 
mystring.replace(reg, 'arrayname[2]'); 

但失敗並顯示錯誤消息說:「RegExp.quote不是一個函數」。

我是否缺少一些簡單的東西?

+1

請注意,我們目前正在[添加這個有趣的工作如果您對此有任何意見,請加入討論。(https://github.com/benjamingr/RegExp.escape) – 2015-06-23 11:37:56

回答

167

這個問題讓我在Google上搜索一個JavaScript中的RegEx.quote函數,我不知道這個函數。事實證明,該功能只存在於一個地方,即在answer by Gracenote here on StackOverflow。該函數的定義如下:

RegExp.quote = function(str) { 
    return (str+'').replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"); 
}; 

如果要使用此功能,你需要的地方在那裏使用的功能,在你的腳本點上方包括上述定義。

+44

現在SO在它們存在之前就會產生問題的答案! – RedFilter 2010-04-07 15:20:12

+6

這是一個整潔的功能,但重要的是要小心這樣的事情。它只在知道包含模式的字符串實際上不打算用真正的正則表達式元字符進行解釋時才起作用。 – Pointy 2010-04-07 15:21:51

+0

@Pointy:我只能同意! – 2010-04-07 15:27:34

2

嗯,首先,你可以有自己的固定的語法定義正則表達式:

var reg = /arrayname\[1\]/; 

裏面的正則表達式你引用的東西用反斜槓。現在,如果你從一個字符串開始,你必須「保護」字符串常量內的反斜槓。在這種情況下,圖案被解析兩次:一旦當字符串常數用的Javascript解析器由正則表達式構造吞噬,然後一旦:

var pattern = "arrayname\\[1\\]"; 
var reg = new RegExp(pattern); 

反斜槓加倍,使得字符串「圖案「將看起來像我的第一個示例中的正則表達式 - 每個括號字符之前的反斜槓。

+0

這裏的事情是我們不知道哪一個是字符串。 – levhita 2012-11-24 18:24:14

24

如果要替換從字面上看,你並不需要擺在首位一個正則表達式:

str = str.split(search).join(replace) 
+4

Upvoted,但你有時需要結合用戶輸入與你自己的正則表達式,在這種情況下,你不能只是做到上述。 – 2012-06-01 06:24:33

22

mozilla dev docs

function escapeRegExp(string){ 
    return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); 
} 

這是不尋常的,但在這特別情況下,我會創建一個這樣的功能

RegExp.escape = function(str) { 
    return String(str).replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); 
}; 

用法

new RegExp(RegExp.escape('http://www.google.com')); 
//=> /http\:\/\/www\.google\.com/ 
15

以下是Google的閉包庫使用的確切函數。

/** 
* Escapes characters in the string that are not safe to use in a RegExp. 
* @param {*} s The string to escape. If not a string, it will be casted 
*  to one. 
* @return {string} A RegExp safe, escaped copy of {@code s}. 
*/ 
goog.string.regExpEscape = function(s) { 
    return String(s).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1'). 
     replace(/\x08/g, '\\x08'); 
}; 

link

+1

但我不知道爲什麼他們特別替換'\ x08'。你知道他們說什麼,谷歌以神祕的方式工作。 – 2014-09-13 02:29:18

+0

@CamiloMartin因爲'\ b'在正則表達式中聲明瞭單詞邊界,但是是在字符串中退格的單個字符轉義符 '/\b/.test('\b'); //假' '/\x08/.test('\b'); // true' – Xaekai 2015-04-09 17:00:07

+0

@Xaekai它們是兩種不同的解析上下文。當你在字符串中寫入'\ b'時,它會被轉換成'\ x08',但是我懷疑'\ b'在寫成正則表達式時會被內部轉換爲'\ x08'。請參閱(在Chrome中測試):'(new RegExp('\ x08'))。test('word boundary')=== false'。但是你所說的話有點意思,也許一些舊的IE會將'\ b'解析爲RegExp的'\ x08'。 – 2015-04-11 22:13:14

15
var easiest = any_string.replace(/\W/g, "\\$&"); 

編輯:

我爲什麼應該記住哪些字符具有特殊的含義,或者即使逃避任何非文字字符是足夠使用的功能?

我的解決方案毫無疑問,也許這就是爲什麼它被拒絕投票。 :D

+1

哈哈哈。盡你所能向我投票。 :D – Ando 2014-12-05 22:49:24

+0

這是爲什麼downvoted? – 2014-12-09 20:28:37

+2

我認爲這不應該是downvoted,因爲下面的文章似乎很穩固,並建議稍微改進版本,即使我仍然不確定它會覆蓋哪些額外的情況:'str。替換(/ [^ \ w \ s]/g,「\\ $&」)'http://eloquentjavascript.net/09_regexp.html _(btw不要把它與''str.replace(/ [\ W \ S ]/g,「\\ $&」)'_在這裏解釋:http://www.regular-expressions.info/shorthand.html)_ – 2014-12-10 13:06:26

相關問題