JavaScript学习笔记整理(13):正则表达式
正则表达式(regular expression)是一个描述字符模式的对象。JavaScript的RegExp类表示正则表达式,String和RegExp都定义了方法。
var pattern = /s$/;
var pattern = new RegExp('s');
\0 匹配null字符(\u0000)。
[\b] 匹配退格键(\u0008),不要与\b混淆。
\t 匹配制表符tab(\u0009)。
\n 匹配换行键(\u000A)。
\v 匹配垂直制表符(\u000B)。
\f 匹配换页符(\u000C)。
\r 匹配回车键(\u000D)。
\xnn 匹配一个以两位十六进制数(\x00-\xFF)表示的字符。
\uxxx 匹配一个以四位十六进制数(\u0000-\uFFFF)表示的unicode字符。
\cX 表示Ctrl-[X],其中的X是A-Z之中任一个英文字母,用来匹配控制字符。
[...] 方括号内的任意字符
[^...]不在方括号内的任意字符
. 除换行符和其他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] 退格直接量
{n,m} 匹配前一项至少n次,至多m次
{n,} 匹配前一项n次或者更多次,也可以说至少n次
{n} 匹配前一项n次
? 匹配前一项0次或者1次,等价于{0,1}
+ 匹配前一项1次或多次,等价于{1,}
* 匹配前一项0次或多次,等价于{0,}
/a+/.exec('aaa') //["aaa"]
/a+?/.exec('aaa') //["a"]
/(.)b(.)\1b\2/.test('abcabc') //true
/(a|b)c\1/.test('aca') //true
/(a|b)c\1/.test('acb') //false
| 选择,匹配的是该符号左边的子表达式或右边的子表达式
(...) 组合,将几个项组合为一个单位,这个单位可通过“*”、“+”、“?”和“|”等符号加以修饰,而且可以记住和这个组合相匹配的字符串以供此后的引用使用。
(?...) 只组合,把项组合到一个单位,但不记忆与该组相匹配的字符
\n 和第n个分组第一次匹配的字符相匹配,组是圆括号中的子表达式(也有可能是嵌套的),组索引是从左到右的左括号数,“(?:”形式的分组不编码
1.1.6 指定匹配位置
除了匹配字符串中的字符外,有些正则表达式的元素匹配的是字符之间的位置,亦可称为正则表达式的锚。比如:\b匹配一个单词的边界,即位于\w(ASCII单词)字符和\W(非ASCII单词)之间的边界,或位于一个ASCII单词与字符串的开始或结尾之间的边界。
正则表达式中的锚字符:
^ 匹配字符串的开头,在多行检索中,匹配一行的开头
$ 匹配字符串的结尾,在多行检索中,匹配一行的结尾
\b 匹配一个单词的边界
\B 匹配非单词边界的位置
(?=p) 零宽正向先行断言,要求接下来的字符都与p匹配,但不能包括匹配p的那些字符
(?!p) 零宽负向先行断言,要求接下来的字符不与p匹配
1.1.7 修饰符
正则表达式的修饰符,用以说明高级匹配模式的规则。修饰符是放在“/”符号之外的,也就是说,它们不是出现在两条斜杠之间的,而是在第二条斜杠之后。
在JavaScript中,支持三个修饰符:
i 执行不区分大小写的匹配
g 执行一个全局匹配,即找到所有的匹配,而不是在找到第一个之后就停止
m 多行模式匹配,在这种模式下,如果待检索的字符串包含多行,那么^和$锚字符除了匹配整个字符串的开始和结尾之外,还能匹配每行的开始和结尾
这些修饰符可以任意组合。比如:
/test/ig
1.2 用于模式匹配的String方法
String支持4种使用正则表达式的方法。
search():按照给定的正则表达式进行搜索,返回一个整数,表示第一个与之匹配的字符串的起始位置,如果找不到匹配的子串,将返回-1。
match():返回一个数组,成员是所有匹配的子字符串。
replace():按照给定的正则表达式进行替换,返回替换后的字符串。
split():按照给定规则进行字符串分割,返回一个数组,包含分割后的各个成员。
1.2.1 search()
"javascript".search(/script/i);
上面的代码的返回值为4
如果search()的参数不是正则表达式,则首先会通过RegExp构造函数将它转换成正则表达式,search()方法不支持全局检索,因为它忽略正则表达式参数中的修饰符g。
1.2.2 match()
match()方法的唯一参数是一个正则表达式,返回的是一个由匹配结果组成的数组。如果该正则表达式设置了修饰符g,则返回的数组包含字符串中的所有匹配结果。
'1 plus 2 equals 3'.match(/\d+/g) //返回["1","2","3"]
返回来的数组还带有另外两个属性:index和input,分别表示包含发生匹配的字符位置和引用的正在检索的字符串。
1.2.3 replace()
replace()方法用以执行检索与替换操作。其中第一个参数是一个正则表达式,第二个参数是要进行替换的字符串。
如果replace()的第一个参数是字符串而不是正则表达式,则replace()将直接搜索这个字符串,而不会像search()一样首先通过RegExp()将它转换为正则表达式。
replace方法的第二个参数可以使用美元符号$,用来指代所替换的内容。
$& 指代匹配的子字符串。
$` 指代匹配结果前面的文本。
$' 指代匹配结果后面的文本。
$n 指代匹配成功的第n组内容,n是从1开始的自然数。
$$ 指代美元符号$。
比如:
'hello world'.replace(/(\w+)\s(\w+)/, '$2 $1')
// "world hello"
replace方法的第二个参数还可以是一个函数,将每一个匹配内容替换为函数返回值。
'abca'.replace(/a/g,function(match){
return match.toUpperCase();
});
// "AbcA"
replace()方法的第二个参数可以接受多个参数。第一个参数是捕捉到的内容,第二个参数是捕捉到的组匹配(有多少个组匹配,就有多少个对应的参数)。
1.2.4 split()
split()方法用以将调用它的字符串拆分为一个子串组成的数组。
'123,456,789'.split(',') //返回["123","456","789"]
split()方法的参数也可以是一个正则表达式。
1.3 RegExp对象
RegExp()构造函数带有两个字符串参数,第二个参数是可选的,它指定正则表达式的修饰符(可传入修饰符g、i、m或者它们的组合);第一个参数包含正则表达式的主体部分,也就是正则表达式直接量中两条斜线之间的文本。
var regexp = new RegExp('\\d{5}','g')
上面的代码表示会全局的查找5个数字。
1.3.1 RegExp对象的属性
每个RegExp对象都包含5个属性:
source 只读字符串,包含正则表达式的文本
global 只读布尔值,用以说明这个正则表达式是否带有修饰符g
ignoreCase 只读布尔值,用以说明正则表达式是否带有修饰符i
multiline 只读布尔值,用以说明正则表达式是否带有修饰符m
lastIndex 可读写的整数,如果匹配模式带有g修饰符,这个属性存储在整个字符串中下一次检索的开始位置。
1.3.2 RegExp的方法
RegExp对象定义了两个用于执行模式匹配操作的方法。
(1)exec()
正则对象的exec方法,可以返回匹配结果。如果发现匹配,就返回一个数组,成员是每一个匹配成功的子字符串,否则返回null。
/a|b|c/.exec('abc') // ["a"]
/a|b|c/.exec('qwe') // null
(2)test()
正则对象的test方法返回一个布尔值,表示当前模式是否能匹配参数字符串。
var s = /a/g;
var a = 'baba';
s.lastIndex //0
s.test(a); //true
s.lastIndex; //2
s.test(a); //true
注意:如果正则表达式带有g修饰符,则每一次test方法都从上一次结束的位置开始向后匹配,也可以通过正则对象的lastIndex属性指定开始搜索的位置。