首页 > 代码库 > 正则表达式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