正如我們所見,反斜線 \ 用於表示字元類別,例如 \d。因此,它在正規表示法中是一個特殊字元(就像在一般字串中一樣)。
還有其他特殊字元在正規表示法中具有特殊意義,例如 [ ] { } ( ) \ ^ $ . | ? * +。它們用於執行更強大的搜尋。
不要試著記住清單——我們很快就會處理它們中的每一個,你會自動地熟記它們。
跳脫
假設我們想要找到一個句點。不是「任何字元」,而只是一個句點。
若要將特殊字元用作一般字元,請在前面加上反斜線:\.。
這也稱為「跳脫字元」。
例如
alert( "Chapter 5.1".match(/\d\.\d/) ); // 5.1 (match!)
alert( "Chapter 511".match(/\d\.\d/) ); // null (looking for a real dot \.)
括號也是特殊字元,因此如果我們要使用括號,應使用 \(。以下範例會尋找字串 "g()"
alert( "function g()".match(/g\(\)/) ); // "g()"
如果我們要尋找反斜線 \,它在一般字串和正規表示式中都是特殊字元,因此我們應將它加倍。
alert( "1\\2".match(/\\/) ); // '\'
斜線
斜線符號 '/' 不是特殊字元,但在 JavaScript 中,它用於開啟和關閉正規表示式:/...pattern.../,因此我們也應跳脫它。
以下是尋找斜線 '/' 的範例
alert( "/".match(/\//) ); // '/'
另一方面,如果我們不使用 /.../,而是使用 new RegExp 建立正規表示式,則我們不需要跳脫它
alert( "/".match(new RegExp("/")) ); // finds /
new RegExp
如果我們使用 new RegExp 建立正規表示式,則我們不必跳脫 /,但需要執行其他跳脫。
例如,考慮以下範例
let regexp = new RegExp("\d\.\d");
alert( "Chapter 5.1".match(regexp) ); // null
先前範例中的類似搜尋使用 /\d\.\d/,但 new RegExp("\d\.\d") 無法運作,為什麼?
原因是反斜線會被字串「消耗」。如我們所知,一般字串有自己的特殊字元,例如 \n,而反斜線用於跳脫。
以下是「\d.\d」的解讀方式
alert("\d\.\d"); // d.d
字串引號會「消耗」反斜線並自行詮釋,例如
\n– 變成換行字元,\u1234– 變成具有此代碼的 Unicode 字元,- …而當沒有特殊意義時:例如
\d或\z,則反斜線會直接移除。
因此 new RegExp 會取得沒有反斜線的字串。這就是搜尋無法運作的原因!
若要修正此問題,我們需要將反斜線加倍,因為字串引號會將 \\ 變成 \
let regStr = "\\d\\.\\d";
alert(regStr); // \d\.\d (correct now)
let regexp = new RegExp(regStr);
alert( "Chapter 5.1".match(regexp) ); // 5.1
摘要
- 若要搜尋特殊字元
[ \ ^ $ . | ? * + ( ),我們需要在前面加上反斜線\(「跳脫它們」)。 - 如果我們在
/.../內(但不在new RegExp內),我們也需要跳脫/。 - 當將字串傳遞給
new RegExp時,我們需要將反斜線加倍\\,因為字串引號會消耗其中一個反斜線。
留言
<code>標籤,對於多行 - 將它們包裝在<pre>標籤中,對於超過 10 行 - 使用沙盒 (plnkr,jsbin,codepen…)