2021 年 10 月 25 日

跳脫,特殊字元

正如我們所見,反斜線 \ 用於表示字元類別,例如 \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 時,我們需要將反斜線加倍 \\,因為字串引號會消耗其中一個反斜線。
教學課程地圖

留言

在評論前請先閱讀…
  • 如果你有改進建議 - 請 提交 GitHub 問題 或拉取請求,而不是評論。
  • 如果你無法理解文章中的某個部分 - 請詳細說明。
  • 要插入幾行程式碼,請使用 <code> 標籤,對於多行 - 將它們包裝在 <pre> 標籤中,對於超過 10 行 - 使用沙盒 (plnkrjsbincodepen…)