字符類(class)表示有一系列字符可供選擇,只要匹配其中一個就可以了。所有可供選擇的字符都放在方括號內,比如`[xyz]`表示`x`、`y`、`z`之中任選一個匹配。
~~~
/[abc]/.test('hello world') // false
/[abc]/.test('apple') // true
~~~
上面代碼中,字符串`hello world`不包含`a`、`b`、`c`這三個字母中的任一個,所以返回`false`;字符串`apple`包含字母`a`,所以返回`true`。
有兩個字符在字符類中有特殊含義。
**(1)脫字符(^)**
如果方括號內的第一個字符是`[^]`,則表示除了字符類之中的字符,其他字符都可以匹配。比如,`[^xyz]`表示除了`x`、`y`、`z`之外都可以匹配。
~~~
/[^abc]/.test('bbc news') // true
/[^abc]/.test('bbc') // false
~~~
上面代碼中,字符串`bbc news`包含`a`、`b`、`c`以外的其他字符,所以返回`true`;字符串`bbc`不包含`a`、`b`、`c`以外的其他字符,所以返回`false`。
如果方括號內沒有其他字符,即只有`[^]`,就表示匹配一切字符,其中包括換行符。相比之下,點號作為元字符(`.`)是不包括換行符的。
~~~
var s = 'Please yes\nmake my day!';
s.match(/yes.*day/) // null
s.match(/yes[^]*day/) // [ 'yes\nmake my day']
~~~
上面代碼中,字符串`s`含有一個換行符,點號不包括換行符,所以第一個正則表達式匹配失敗;第二個正則表達式`[^]`包含一切字符,所以匹配成功。
> 注意,脫字符只有在字符類的第一個位置才有特殊含義,否則就是字面含義。
**(2)連字符(-)**
某些情況下,對于連續序列的字符,連字符(`-`)用來提供簡寫形式,表示字符的連續范圍。比如,`[abc]`可以寫成`[a-c]`,`[0123456789]`可以寫成`[0-9]`,同理`[A-Z]`表示26個大寫字母。
~~~
/a-z/.test('b') // false
/[a-z]/.test('b') // true
~~~
上面代碼中,當連字號(dash)不出現在方括號之中,就不具備簡寫的作用,只代表字面的含義,所以不匹配字符`b`。只有當連字號用在方括號之中,才表示連續的字符序列。
以下都是合法的字符類簡寫形式。
~~~
[0-9.,]
[0-9a-fA-F]
[a-zA-Z0-9-]
[1-31]
~~~
上面代碼中最后一個字符類`[1-31]`,不代表`1`到`31`,只代表`1`到`3`。
連字符還可以用來指定 Unicode 字符的范圍。
~~~
var str = "\u0130\u0131\u0132";
/[\u0128-\uFFFF]/.test(str)
// true
~~~
上面代碼中,`\u0128-\uFFFF`表示匹配碼點在`0128`到`FFFF`之間的所有字符。
另外,不要過分使用連字符,設定一個很大的范圍,否則很可能選中意料之外的字符。最典型的例子就是`[A-z]`,表面上它是選中從大寫的`A`到小寫的`z`之間52個字母,但是由于在 ASCII 編碼之中,大寫字母與小寫字母之間還有其他字符,結果就會出現意料之外的結果。
~~~
/[A-z]/.test('\\') // true
~~~
上面代碼中,由于反斜杠('\\')的ASCII碼在大寫字母與小寫字母之間,結果會被選中。
- 第一章:變量與作用域
- 第一節:變量
- 第二節:執行環境及作用域
- 第三節:JS 解析機制
- 第四節:垃圾收集
- 第二章:深入函數
- 第一節:概述
- 第二節:函數聲明
- 第三節:函數調用
- 第四節:函數參數
- 第五節:函數返回值
- 第三章:面向對象
- 第一節:概述
- 第二節:對象聲明
- 第三節:this 關鍵字
- 第四節:對象遍歷
- 第五節:對象繼承
- 第六節:模塊
- 第四章:正則表達式
- 第一節:概述
- 第二節:實例屬性
- 第三節:實例方法
- 第一課時:測試
- 第二課時:執行
- 第四節:匹配規則
- 第一課時:字面量字符和元字符
- 第二課時:轉義符
- 第三課時:特殊字符
- 第四課時:字符類
- 第五課時:預定義模式
- 第六課時:重復類
- 第七課時:量詞符
- 第八課時:貪婪模式
- 第九課時:修飾符
- 第十課時:組匹配
- 第五節:字符串的實例方法
- 第一課時:匹配
- 第二課時:搜索
- 第三課時:替換
- 第四課時:分割