2021 年 12 月 12 日

字元類別

考慮一個實際任務 – 我們有一個像 "+7(903)-123-45-67" 這樣的電話號碼,而我們需要將其轉換成純數字:79031234567

為此,我們可以找出並移除任何不是數字的東西。字元類別可以協助處理這項任務。

字元類別是一種特殊符號,用於比對特定集合中的任何符號。

首先,我們來探討「數字」類別。它寫作 \d,並對應到「任何單一數字」。

例如,讓我們找出電話號碼中的第一個數字

let str = "+7(903)-123-45-67";

let regexp = /\d/;

alert( str.match(regexp) ); // 7

沒有旗標 g,正規表示式只會尋找第一個符合的字元,也就是第一個數字 \d

讓我們加上 g 旗標來尋找所有數字

let str = "+7(903)-123-45-67";

let regexp = /\d/g;

alert( str.match(regexp) ); // array of matches: 7,9,0,3,1,2,3,4,5,6,7

// let's make the digits-only phone number of them:
alert( str.match(regexp).join('') ); // 79031234567

那是一個數字字元類別。還有其他字元類別。

最常用的有

\d(「d」來自於「digit」,數字)
一個數字:一個從 09 的字元。
\s(「s」來自於「space」,空白)
一個空白符號:包含空白、跳格 \t、換行 \n 和其他幾個較少見的字元,例如 \v\f\r
\w(「w」來自於「word」,字)
一個「字」元:一個拉丁字母、一個數字或一個底線 _。非拉丁字母(例如西里爾字母或印度文)不屬於 \w

例如,\d\s\w 表示一個「數字」,後接一個「空白字元」,後接一個「字元」,例如 1 a

一個正規表示式可以同時包含一般符號和字元類別。

例如,CSS\d 會符合一個字串 CSS,後接一個數字

let str = "Is there CSS4?";
let regexp = /CSS\d/

alert( str.match(regexp) ); // CSS4

我們也可以使用多個字元類別

alert( "I love HTML5!".match(/\s\w\w\w\w\d/) ); // ' HTML5'

符合的字元(每個正規表示式字元類別都有對應的結果字元)

反向類別

對於每個字元類別,都有一個「反向類別」,表示方式為相同字母,但使用大寫。

「反向」表示它會符合所有其他字元,例如

\D
非數字:任何字元,除了 \d,例如一個字母。
\S
非空白:任何字元,除了 \s,例如一個字母。
\W
非字元:任何字元,除了 \w,例如一個非拉丁字母或一個空白。

在章節的開頭,我們看過如何從一個像 +7(903)-123-45-67 這樣的字串中,產生一個只有數字的電話號碼:找出所有數字並將它們串接起來。

let str = "+7(903)-123-45-67";

alert( str.match(/\d/g).join('') ); // 79031234567

一個替代的、較短的方法是找出非數字 \D 並將它們從字串中移除

let str = "+7(903)-123-45-67";

alert( str.replace(/\D/g, "") ); // 79031234567

一個點代表「任何字元」

一個點 . 是特殊字元類別,用來比對「任何字元,除了換行符號」。

例如

alert( "Z".match(/./) ); // Z

或在正規表示式中間

let regexp = /CS.4/;

alert( "CSS4".match(regexp) ); // CSS4
alert( "CS-4".match(regexp) ); // CS-4
alert( "CS 4".match(regexp) ); // CS 4 (space is also a character)

請注意,一個點代表「任何字元」,但不是「沒有字元」。必須有字元與之比對

alert( "CS4".match(/CS.4/) ); // null, no match because there's no character for the dot

點代表任何字元,使用「s」旗標

預設情況下,一個點不會比對換行字元 \n

例如,正規表示式 A.B 比對 A,然後比對 B,中間可以有任何字元,但不能是換行符號 \n

alert( "A\nB".match(/A.B/) ); // null (no match)

在許多情況下,我們希望一個點代表「任何字元」,包括換行符號。

這就是旗標 s 的作用。如果正規表示式有這個旗標,那麼一個點 . 就會比對任何字元

alert( "A\nB".match(/A.B/s) ); // A\nB (match!)
IE 不支援

IE 不支援 s 旗標。

幸運的是,有一個替代方案,可以在所有地方使用。我們可以使用像 [\s\S] 的正規表示式來比對「任何字元」(此模式將在文章 集合和範圍 [...] 中介紹)。

alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!)

模式 [\s\S] 實際上表示:「一個空白字元或不是空白字元」。換句話說,就是「任何東西」。我們可以使用另一對互補類別,例如 [\d\D],這並不重要。甚至可以使用 [^],因為它的意思是比對任何字元,除了沒有字元。

此外,如果我們希望在同一個模式中同時使用兩種「點」,我們可以使用這個技巧:實際的點 . 以一般方式運作(「不包括換行符號」),並使用 [\s\S] 或類似的來比對「任何字元」。

注意空格

我們通常不太注意空格。對我們來說,字串 1-51 - 5 幾乎相同。

但是,如果正規表示式沒有考慮空格,它可能會無法運作。

我們嘗試尋找以連字號分隔的數字

alert( "1 - 5".match(/\d-\d/) ); // null, no match!

我們透過在正規表示式 \d - \d 中加入空格來修正它

alert( "1 - 5".match(/\d - \d/) ); // 1 - 5, now it works
// or we can use \s class:
alert( "1 - 5".match(/\d\s-\s\d/) ); // 1 - 5, also works

空格是一個字元。與其他任何字元一樣重要。

我們不能在正規表示式中新增或移除空格,並期望它運作相同。

換句話說,在正規表示式中,所有字元都很重要,包括空格。

摘要

存在下列字元類別

  • \d – 數字。
  • \D – 非數字。
  • \s – 空白符號、標籤、換行符。
  • \S – 所有字元,但排除 \s
  • \w – 拉丁字母、數字、底線 '_'
  • \W – 所有字元,但排除 \w
  • . – 任何字元,若加上 regexp 's' 旗標,則為任何字元,但排除換行符 \n

…但這還不是全部!

JavaScript 用於字串的 Unicode 編碼提供許多字元屬性,例如:字母屬於哪種語言(如果是字母)、是否為標點符號等等。

我們也可以透過這些屬性進行搜尋。這需要 u 旗標,我們將在下篇文章中介紹。

教學課程地圖

留言

留言前請先閱讀…
  • 如果您有改善建議,請 提交 GitHub 問題 或發起拉取請求,而不是留言。
  • 如果您無法理解文章中的某些內容,請詳細說明。
  • 若要插入少許程式碼,請使用 <code> 標籤,若要插入多行程式碼,請用 <pre> 標籤包覆,若要插入超過 10 行的程式碼,請使用沙盒(plnkrjsbincodepen…)