Regular Expression是一个描述符合匹配条件的字符串的字符串,在js中有对应的RegExp对象来存储正则表达式。
在js中实例化RegExp对象有两种方法:
1.用字面量的形式 var reg=/ \b searchword \b /g,即/要匹配字符/+修饰符
其中,/…/表明内容是正则表达式,\b代表单词边界word boundary,g代表全局搜索global,为了方便观看在各符号之间加了空格,实际代码中只能写成/\bsearchword\b/
2.使用构造函数 var reg=new RegExp(\bsearchword\b,g),即RegExp(表达式,修饰符)
RegExp对象的语法:
修饰符
g global——执行全局匹配,如果不加则会在匹配到第一个符合条件的字符/字符串时停止继续替换
i ignoreCase——忽略大小写
m multiline——执行多行匹配(忽略\r\n)
用法:加在/…/之后
元字符
元字符是指含有特殊含义的字符,通常由转义符\+字母表示或者 * + ? $ ^ ...等符号来表示
\+字母类:
\w word单词字符,可以匹配a-z、A-Z、0-9、_下划线
\d digital数字,可以匹配0-9
\b boundary边界,匹配单词边界
例:"This is a boy".replace(/is/,IS)→ThIS IS a boy,而"This is a boy".replace(/\bis\b/,IS)→This IS a boy。
\s 空白字符,可以匹配空格字符及其他空白字符如回车\r、换行\r、制表\t
\t table水平制表
\v vertical垂直制表
\r carriage return移动光标到当前行的最左边
\n new line移动光标到下一行,不会产生左右移动
关于回车与\r、\n的关系:
由上图可知,在Win系统下浏览器解析文件中的回车键Enter=\r\n,即先光标左移后光标下移。
在Linux下Enter=\n,在Mac下Enter=\r。
\0 空字符,匹配null
\f 换页符
\cX 匹配ctrl+X
↑注意在' '中反斜杠要生效需要经过转义所以是\\b,使用/ /则无需转义
符号类元字符(不全):
. 表示除了\r、\n之外的任意字符
^表示取反
补充一点,\d表示匹配0-9的数字,只需将其大写为\D则表示匹配所有不是数字的字符,\w、\s等以此类推
? 表示出现0次或1次
+ 表示出现1次或多次
* 表示出现0次或多次
$ 与()搭配使用表示反引用,当然还有其他作用
( ) 表示分组
{ } 表示量词
[ ] 表示范围
方括号[ ]
[ ]在正则表达式中我喜欢将其解释成集合。
[0-9]、[a-z]、[a-zA-Z]即为匹配这个范围内的数字,注意第三种写法,在[ ]可以这样连写
[abc]为在字符串中匹配a或b或c字母其中的一个,注意并不是匹配abc
[^abc]为在字符串中匹配除了a、b、c以外的所有字符
量词{ }
在字符串替换中,如出现对多个相同类型的字符进行替换,可以用量词来简化表达式。
{n} 表示出现n次 /\d{3}/ = /\d\d\d/,匹配3个数字,\d=[0-9]
{n,m} 表示出现n~m次 /\d{3,6}/,匹配3-6个数字
对于{n,m}存在贪婪和非贪婪两种模式,在贪婪模式下会尽可能多的匹配,如对字符串“abc1234567def”进行(/\d{3,6}/,0)的替换结果是abc07def。而在非贪婪模式下(/\d{3,6?}/, 0)的替换结果是abc04567def,会尽可能少的匹配。非贪婪模式表达方式为{n,m?}。
{n,} 表示至少出现n次
? 表示出现0次或1次 /bo?y/表示可以匹配by、boy
+ 表示出现1次或多次 /bo+y/表示可以匹配boy、boooy、boooooooy等
* 表示出现0次或多次 /bo*y/表示可以匹配by、boy、boooooy等
注意:{n}、?等只作用于紧挨着的前一个字符,即/bo{3}y/=boooy,/bo+y/=boy、booooy。。。
↑通过https://regexper.com/提供的可视化解释可以帮助我们理解正则表达式
分组( )
使用()可以使量词对多个字符生效,如/(abc){3}/ 就相当于"abcabcabc"
使用()可以捕获匹配到的内容,并通过$+数字进行反引用
如我们要将2017-10-1替换为10/1/2017:
因为日期是变量,所以这里使用+量词而不使用{4}、{2}、{2}
如果我们要禁止()捕获内容,要这样书写(?:+表达式),如(?:\d{4})
前瞻
js读取文本时的顺序是从前向后,这里的前瞻是指匹配了对应内容的字符但还要继续向后看,检查后面字符是否符合额外的条件,然后进行替换,替换内容不包括前瞻内容。
前瞻的表达方法为:/表达式(?=额外的表达式条件)/
下例为将4个字母后还带有3个数字的4个字母进行替换
令人伤心的是js并不支持后顾,也就是说如我想单独的替换"@123@456@"中"3@4"中的"@4"将无法实现,因为@1和@4将没有办法区分。
RegExp对象的属性与方法
RegExp对象的属性
global、ignorecase、multiline 文章开头已说过
lastIndex 如果启用了全局搜索g,则会在每一次匹配后获得匹配成功的内容中最后一个字符的下一个字符的位置,需要搭配RegExp对象的test()方法使用。
source 返回正则表达式的文本内容
RegExp对象的方法
test()
检测字符串中是否存在符合正则表达式的字符串,有则返回ture,没有则返回false
用法:RegExpObject.test(stringObject)
匹配成功后会更改RegExp中的lastIndex属性,如果启用了g选项的话,lastIndex为当前匹配成功的字符串中最后一个字符的下一个字符的位置
exec()
检测字符串中是否存在符合正则表达式的字符串,如果有则返回一个字符串数组,数组的内容是匹配的字符串,数组有额外2个属性index和input,index存放上次匹配成功的字符串内容的第一个字符所在的位置,input存放原检索字符串的引用,没有则返回null。
用法同上
string对象的方法
string对象的方法配合正则表达式使用方法为:stringObject.function(RegExpObject)
search() 并不执行全局匹配/查找。 "123abc3a".search(/3a/g) 返回index(查找成功的第一个字符串内容中第一个字符的位置),如果查找失败返回-1
match() 寻找1个以上与正则表达式匹配的字符串内容。
在非g情况下,执行后返回字符串数组,第一个元素存放的是匹配的字符串内容;第二~第n存放匹配子表达式的字符串内容,比如使用了()分组,则()内与表达式 符合的字符串内容将依次存放进第二~第n个元素中。返回的数组还包括2个属性,index存放匹配文本的首字符在原字符串中的位置;input存放对原字符串对象的引用。
在带g模式下,match()返回字符串数组,有n个元素,存放匹配成功的n个字符串,不会存放()符合分组表达式的字符串内容,数组没有index、input属性。
replace() 把字符串中符合条件的内容替换
用法stringObject.replace(RegExpObject,stringObject)这个很简单不再解释
或stringObject.replace(RegExpObject,function())
对于function()如果设置了形参,则会默认依次传递以下参数:
1.匹配字符串
2.正则表达式分组内容(),如果没有分组则跳过
3.匹配项在原字符串中的index
4.原字符串
下例将"a1b2c3d4e55f666g7"中的数字字符全部替换为自身+1
当reg为g模式时,replace函数会循环调用自身
split() 用于把一个字符串分割成字符串数组
用法:stringObject.split(RegExp),将RegExp作为分隔符分割字符串,当然也可以使用字符做分隔符,使用""做分隔符时,会将字符串的每个字符分割开。
小结:
js中正则表达式的学习就到此为止了,要掌握好正则表达式主要是对语法规则有深入的了解。原来的string对象的replace()、search()、match()等方法可以传入string对象,但实质都是转换为正则表达式。string对象的方法不会修改原对象的值。