### 正则表达式
正则表达式是一个描述字符串模式的对象,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
```