考慮一個實際任務 – 我們有一個像 "+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」,數字)- 一個數字:一個從
0
到9
的字元。 \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 不支援 s
旗標。
幸運的是,有一個替代方案,可以在所有地方使用。我們可以使用像 [\s\S]
的正規表示式來比對「任何字元」(此模式將在文章 集合和範圍 [...] 中介紹)。
alert( "A\nB".match(/A[\s\S]B/) ); // A\nB (match!)
模式 [\s\S]
實際上表示:「一個空白字元或不是空白字元」。換句話說,就是「任何東西」。我們可以使用另一對互補類別,例如 [\d\D]
,這並不重要。甚至可以使用 [^]
,因為它的意思是比對任何字元,除了沒有字元。
此外,如果我們希望在同一個模式中同時使用兩種「點」,我們可以使用這個技巧:實際的點 .
以一般方式運作(「不包括換行符號」),並使用 [\s\S]
或類似的來比對「任何字元」。
我們通常不太注意空格。對我們來說,字串 1-5
和 1 - 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
旗標,我們將在下篇文章中介紹。
留言
<code>
標籤,若要插入多行程式碼,請用<pre>
標籤包覆,若要插入超過 10 行的程式碼,請使用沙盒(plnkr、jsbin、codepen…)