首页 > 代码库 > 正则表达式Regular Expression
正则表达式Regular Expression
什么是 RegExp?
RegExp 是正则表达式的缩写。
正则表达式( regular expression)描述了一种字符串匹配的模式。可以用来:
(1)检查一个串中是否含有符合某个规则的子串,并且可以得到这个子串;
(2)根据匹配规则对字符串进行灵活的替换操作
正则表达式在线测试网站,https://regexper.com/
通过该网站,可以通过图形化的界面去领会正则表达式的含义,将更加直观和容易理解
RegExp对象:
JavaScript通过内置对象RegExp来支持正则表达式
有两种方法实例化RegExp对象:
1、字面量 :如 var reg = /\bis\b/g;
2、构造函数 : 如 var reg = new RegExp(‘\\bis\\b‘,‘g‘);
修饰符: g:global全文搜索,不添加,搜索到第一个匹配就停止
i:ignore case忽略大小写,默认大小写敏感
m:multiple lines 多行搜索
正则表达式主要有一下两种字符组成:
1、原义文本字符(普通字符):
字母、数字、汉字、下划线、以及没有特殊定义的标点符号,都是"普通字符"表达式中的普通字符。在匹配一个字符串的时候,匹配与之相同一个字符 如:a,b,
2、元字符:
指的是在正则表达式中具有特殊含义的非字母字符(转义字符) ,如\n换行符 \t水平制表符 \v垂直制表符 \r回车符 \o空字符 \f换页符 \cX与X对应的控制字符(ctrl+x)
特殊元字符:. * + $ ^| \(){}[]
字符类:
使用元字符[]来构建的一个简单类,所谓类是指符合某些特性的对象,一个泛指,而不是特质某一个字符,如:[abc]把字符a、b、c归为一类,表达式可以匹配这些字符
[abc]
范围类:
可以使用[a-z]来连接两个字符,表示从a到z的任意字符,这是个闭区间,包含了a和z字符
在[]组成的类内部是可以连写的,比如[a-zA-Z]
预定义类和边界:
匹配一个ab+数字+任意字符 的字符串 如:ab[0-9][^\r\n]
正则表达式提供了几个常用的边界表达式,如图
注意:^放在[]里面,就表示除xxx字符之外,放在外面则表示以xxx开始
量词:
如果希望一个连续出现20次的数字字符串,可以采取这种形式 \d{20}
\d{20}\w\d?\w+\d*\d{3}\w{3,5}\d{3,}
贪婪模式和非贪婪模式:
贪婪模式:\d{3,6} ,尽可能多的匹配
非贪婪模式:让正则表达式尽可能少的匹配,也就是说一旦成功匹配了就不再尝试,在后面加个?号即可
分组:
配置字符串Byron连续出现3次的场景,
Byron{3} 实际效果:
() 圆括号: 可以达到分组的功能,使量词作用于分组
|或:使用|可以达到或的效果 Byron | Casper
也可以这样结合分组使用 Byr(on|Ca)sper
选择出来的是符合Byronsper或者ByronCasper
反向引用
将2015-12-25 =>12/25/2015
前瞻:
正则表达式从文本头部向尾部开始解析,文本尾部方向,称为‘前’
前瞻就是在正则表达式匹配到规则的时候,向前检查是否符合断言,后顾/后瞻方向相反
javascript不支持后顾
符合和不符合特定断言称为肯定/正向匹配和否定/负向匹配
\w(?=\d)
\w(?!\d)
分析:从第一个字符‘a‘开始,满足\w,后跟‘2‘,符合断言‘\d’,因此a被X所替换
分析同上
对象属性:
global全文搜索,不添加,搜索到第一个匹配就停止 默认值false
ignore case忽略大小写,默认大小写敏感 默认值false
multiple lines 多行搜索 ,默认值false
lastIndex:是当前表达式匹配内容的最后一个字符的下一个位置
source:正则表达式的文本字符串
这几个属性都是只读的,不能手动设置
RegExp的test和exec方法:
RegExp.prototype.test(str) :
用于测试字符串参数中是否存在匹配正则表达式模式的字符串
如果存在,返回true,否则返回false
给其加上g后,判断ab是存在匹配该模式的字符, ,从结果看来,当执行到第三次,结果变成了false,其实是lastIndex这个属性在作用,原因在于正则表达式执行了test方法后都会作用到正则表达式本身的结果。,可以看到执行两次后,lastIndex的值变为了2
分析:当前匹配结果,就是a,当前匹配结果的最后一个结果,还是a,当前匹配结果的最后一个结果的下一个结果,那就是b,此时lastIndex的值就是1了。那么在执行一次,lastIndex的结果就是2,看来test方法执行,其lastIndex并不是每次都是从头开始的,那么第3次执行的时候,lastIndex就被重置为0了。
如果测试的是reg1.test(‘a‘);那么其返回的结果,只有奇数次是true。因为我们用test的方法时候,只是为了测试是否存在某个字符而已,因此就没有必要加上g标志了。
RegExp.prototype.exec(str)
使用正则表达式模式对字符串执行搜索,并更新全局RegExp对象的属性以反应匹配结果
如果没有匹配的文本则返回null,否则返回一个结果数组
-index 声明匹配文本的第一个字符的位置
-input 存放被检索的字符串String
非全局调用:
*调用非全局的RegExp对象的exec()时,返回数组
*第一个元素是与正则表达式相匹配的文本
*第二个元素是与RegExpObject的第一个子表达式相匹配的文本(如果有的话)
*第三个元素是与RegExp对象的第二个子表达式相匹配的文本(如果有的话,依次类推)
注意了:在非全局的情况下,lastIndex根本就不生效
以上是非全局和全局调用的结果
字符串对象方法:
String.prototype.search(reg)
*search()方法用于检索字符串中指定子字符串,或检索与正则表达式相匹配的子字符串
*方法返回第一个匹配结果 index,查找不到返回-1
*search()方法不执行全局匹配,它将忽略标志g,并且总是从字符串的开始进行检索
‘a1b2c3’.search(‘1‘);返回1,会将其转换成正则表达式 ‘a1b2c3’.search(/1/);返回1,如果传入的参数不是正则,则会尝试转换成正则表达式
String.prototype.match(reg)
非全局调用:
如果regexp没有标志g,那么match()方法就只能在字符串中执行一次匹配
如果没有找到任何文本,将返回null
否则它将返回一个数组,其中存放了与它找到的匹配文本有关的信息
返回数据的第一个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式(如分组)匹配的文本
除了常规的数组元素之外,返回的数组还含有2个对象属性
-index 声明匹配文本的起始字符在字符串中的位置
-input声明对stringObject的引用
全局调用:
如果regexp具有标志g,则match方法将执行全局搜索,找到字符串中所有匹配子字符串
*没有找到任何匹配的子串,则返回null
*如果找到了一个或多个匹配子串,则返回一个数组
数组元素中存放的是字符串中所有匹配子串,而且也没有index属性或input属性
以上是非全局和全局调用结果,非全局下,lastIndex不起作用,其ret中的a是分组的字符。在全局条件下ret的结果为1a2,3c4
Sting.propotype.split(reg)
我们经常使用split方法把字符串分割为字符数组
‘a1b2c3d4e5‘,split(/\d/);
String.prototype.replace()
‘a1b1c1‘.replace(‘1‘,2) -->‘a2b1c1’,并不是期望
‘a1b1c1’.replace(/1/g,2)-->‘a2b2c2‘
三种参数:
replace(str,replaceStr);
replace(reg,replaceStr);
replace(reg,function); //处理更加复杂的替换结果
采用第三种,用function的返回值作为替换结果,function会在每次匹配替换结果的时候执行四个参数
1、匹配字符串
2、正则表达式分组内容,没有分组则没有参数
3、匹配项在字符串中的index下标
4、原字符串
将‘a1b2c3d4e5‘ ---> ‘a2b3c4d5e6‘
从上看到,两次匹配的结果分别是 1b2 和 2d4,由于分组后,只对group1和group3保留,去掉group2,因此1b2-->12 3d4-->34,最终替换的结果就是a12c34e5
正则表达式Regular Expression