### 正則表達式
正則表達式是一個描述字符串模式的對象,String和RegExp都定義了正則對象的方法,而后者更強大。
正則表達式的定義:
- 使用RegExp()構造函數,如 var pattern = new RegExp("s$")
- 使用/.../直接量,如 var pattern = /s$/
在ES3中,多執行同一段正則表達式直接量都會返回同一個正則對象,而在ES5中,同一段正則表達式執行多次時,每次都返回新對象。
#### 1. 直接量字符
直接量字符在匹配時,直接按照字面含義進行匹配。
|字符 | 匹配 |
| --- | --- |
|字母和數字 |自身 |
|\o | NUL字符(\u0000) |
|\t | 制表符(\u0009) |
|\n | 換行符(\u000A) |
|\v | 垂直制表符(\u000B) |
|\f | 換頁符(\u000C) |
|\r | 回車符(\u000D) |
|\xnn | 由十六進制數nn指定的拉丁字符,例如\x0A等價于\n |
|\uxxxx | 由十六進制數xxxx指定的Unidode字符,如\u0009等價于\t |
|\cX | 控制字符^X,例如\c等價于\n |
在正則中,還有一些其他的特殊標點符號,具有特殊的含義,比如:
^ $ . * + ? = ! : / \ ( ) [ ] { }
#### 2. 字符類
字符類可以匹配它所包含的任意字符,比如/[abc]/可以匹配a,b,c中的任何一個。
|字符類 | 匹配|
|--- | ---|
|[...] | 方括號內的任意字符|
|[^...] | 不包含方括號內的任意字符|
|. | 除換行符和其他Unicode行終止符之外的任意字符|
|\w | 任何ASCII字符組成的單詞,等價于[a-zA-Z0-9]|
|\W | 任何不是ASCII字符組成的單詞,等價于[^a-zA-Z0-9]|
|\s | 任何Unicode空白字符|
|\S | 任何非Unicode空白字符|
|\d | 任何ASCII數字,等價于[0-9]|
|\D | 任何ASCII數字之外的字符,等價于[^0-9]|
|[\b] | 退格直接量(特例)|
#### 3. 重復
|字符 | 含義|
|--- | ---|
|{n,m} | 匹配前一項至少n次,不超過m次|
|{n,} | 匹配前一項n次或更多次|
|{n} | 匹配前一項n次|
|? | 匹配前一項0次或1次,等價于{0,1}|
|+ | 匹配前一項1次或多次,等價于{1,}|
|* | 匹配前一項0次或多次,等價于{0,}|
```
/\d{2,4}/ //匹配2-4個數字
/\w{3}\d?/ //匹配三個單詞和一個可選的數字
/\s+java\s+/ //匹配前后帶一個或多個空格字符的字符串"java"
/[^(]*/ //匹配一個或多個非左括號的字符
```
#### 4. 選擇、分組和引用
##### 字符"|"
字符"|"用以分割供選擇的字符,例如/ab|cd|ef/可以匹配ab,也可以匹配cd,也可以匹配ef。需要注意的是,匹配的次序時從左到右,如果匹配到了,就不會繼續往右。
##### ()
正則表達式中的"()"有兩個作用:
- 把單獨的項目組合成子表達式
- 定義子模式
子表達式:比如/java(script)?/可以匹配"java",也可以匹配"javascript"。/(ab|cd)+|ef/可以匹配ab或cd一次或者多次,也可以匹配ef
子模式:當一個正則表達式成功的和目標字符串匹配時,可以從目標字符串中抽取出和圓括號中子模式匹配的部分。比如有一個字符串,包括一個或多個小寫字母且后面跟了一位或多位數字,則可以使用/[a-z]+\d+/匹配這個字符串。如果要抽取出這些數字,則可以使用/[a-z]+(\d+)/
##### 引用
如果使用了圓括號,則可以允許正則表達式后面部分引用前面的子表達式。使用過在字符\后面加一位或多位數字實現的。這個數子指定了前面圓括號的位置。因為存在子表達式嵌套的情況,所以這個引用時根據左括號的位置計數的。
|字符 | 含義|
|--- | ---|
|\| | 選擇|
|(...) | 組合,將幾個項合成為一個單元,這個單元可以通過"*"、"+"、"\|"等加以修飾|
|(?...) | 只組合,但不記憶與該組匹配的字符|
|\n | 和第n個分組第一次匹配的字符相匹配|
#### 5. 指定匹配位置
|字符 | 含義|
|--- | ---|
|^ | 匹配字符串的開頭|
|$ | 匹配字符串的結尾|
|\b | 匹配單詞的邊界|
|\B | 匹配非單詞邊界的位置|
#### 6. 修飾符
|字符 | 含義|
|--- | ---|
|i | 忽略大小寫|
|g | 全局匹配,找到所有的匹配|
|m | 多行匹配模式|
#### 7. 模式匹配的String方法
##### search
search參數是一個正則表達式,返回第一個與之匹配的子串的起始位置,如果沒有找到匹配的則返回-1.search方法不支持全局檢索,會忽略修飾符g。
```
JavaScript.search(/script/i); //4
```
##### replace
replace方法用于檢索并替換子串,其中第一個參數是正則表達式,第二個是要進行替換的字符串,如果帶有修飾符g則替換所有匹配的子串,如果沒有g則只替換第一個匹配的子串。
```
str.replace(/javascript/ig,"JavaScript"); //將str中所有的javascript都換成大寫的JavaScript
```
##### match
match方法是最常用的String正則表達式方法。它只接受一個正則參數,返回一個數組,數組包含正則所匹配到的結果。
```
"1 plus 2 equals 3".match(/\d+/g); //["1","2","3"],如果沒有g,則match不進行全局檢索
```
#### split
split方法用于對字符串進行分割,其參數可以是一個字符串,也可以是一個正則表達式對象。
```
"123,456,789".split(","); //["123","456","789"]
```
```
"1, 2, 3, 4, 5".split(/\s*,\s*/); //["1","2","3","4","5"]
```
#### 6. RegExp對象
##### RegExp對象的屬性
- source,一個只讀字符串,包含正則表達式的文本
- global,只讀的布爾值,用來說明是否全局匹配
- ingoreCase,只讀的布爾值,用來說明是否忽略大小寫
- multiline,只讀的布爾值,用來說明是否帶有修飾符m
- lastIndex,可讀/寫的整數,如果帶有修飾符g,則這個屬性記錄下一次檢索的開始位置,會被exec和test方法用到
##### RegExp方法
###### exec
exec方法與match方法類似,只不過用法不同,exec方法的參數為原字符串,而match方法參數為正則表達式。
無論exec方法有沒有指定g修飾符,exec都返回同樣的數組,當調用exec時,RegExp對象會將其lastIndex屬性設置為子串的起始位置,每調用一次,都會設置一次。下次調用的時候會從上次的lastIndex位置開始,當沒有匹配到時,回返回null。所以可以利用這特性反復調用exec方法。
exec方法返回一個數組包含了index屬性,表示匹配的子串在原字符串中的起始索引。
```
var pattern = /Java/g;
var text = "JavaScript is more fun than Java";
var result;
while((result = pattern.exec(text))){
alert("Matched '"+result[0]+"'"+"at position "+result.index+"; next search begins at "+pattern.lastIndex);
}
```
###### test
test方法用來檢測字符串中是否包含子串,如果包含則返回true,否則返回false。
```
var pattern = /java/i;
pattern.test("JavaScript"); //true
```