JavaScript中的正则表达式

JavaScript中的正则表达式


ES5中,RegExp构造函数的两种情况
  1. 第一种情况是,参数是字符串,第二个参数表示正则表达式的修饰符:

     var reg=new RegExp('abc','i');  //i修饰符表示忽略大小写,还有g修饰符,表示全局匹配,m修饰符表示多行匹配
     //等价于
     var reg=/abc/i;
    
  2. 第二种是,参数是一个正则表达式,这时会返回一个原有正则表达式的拷贝:

     var reg=new RegExp(/abc/i);
     //依然等价于
     var reg=/abc/i;
     //但在ES5中,这种方式不允许第二个参数添加修饰符,否则就会报错
     var reg=new RegExp(/abc/,'i');   ==>TypeError
     //这种限制在ES6中得到了修正
     RegExp(/abc/ig, 'i').flags  ==>i	  //在ES6中,这种写法不会报错,会改变正则表达式的修饰符,用后写入的i代替原有的ig修饰符
     //同时声明,flags是ES6新增的属性,会返回正则表达式的修饰符
    
正则表达式中的修饰符
  1. u修饰符(Unicode模式):

    • 用于正确处理大于\uFFFF的Unicode字符用于正确处理大于\uFFFF的Unicode字符

       /^\uD83D/u.test('\uD83D\uDC2A') // false
       /^\uD83D/.test('\uD83D\uDC2A') // true
      
    • ES6新增了使用大括号表示Unicode,这种正则表达式必须加上u修饰符,才能识别当中的大括号,否则会被解读为量词

        /\u{61}/.test('a')	==>false//正则表达式无法识别\u{61}这种表示法,只会认为匹配61个连续的u ,具体原因请查看正则表达式基本语法
        /\u{61}/u.test('a')	==>true
      
  2. y修饰符(粘连修饰符)

    • 与g修饰符类似,都是全局匹配,后一次匹配从上一次匹配成功的位置开始.不同之处在于,g修饰符只要剩余位置中存在匹配即可,而y修饰符必须从剩余的的第一个位置开始,也就是所谓的"粘连".下面通过一个例子更好的理解一下

        var s='aaa_aa_a';
        var r1=/a+/g;
        var r2=/a+/y;
        r1.exec(s)  ==>["aaa"]		//exec用于返回符合条件的字符串
        r2.exec(s)  ==>["aaa"]
        //这里再次调用exec
        r1.exec(s)  ==>["aa"]
        r2.exec(s)  ==>null 
        //解释如下:
        首先,r1和r2第一次调用exec匹配,都是从字符串头部开始,因此都能正确匹配到aaa
        第二次调用exec,r1和r2就有了区别,r1使用的是g修饰符,它在匹配aaa之后会直接从后面整个内容中寻找符合条件的字符,经过_后匹配到aa返回
        而r2使用的y修饰符需要从第一次匹配成功后剩余的第一个位置开始匹配,不能跳过,因此第一次匹配后字符串剩余为'_aa_a',第一个位置为_,
        因此匹配不成功,不过跳过_去查找接下来的字符串,直接返回null
      
    • 在split方法中使用y修饰符,原字符串必须以分隔符开头.也就是说,只要匹配成功,数组的第一个成员必定是空字符串

        //先说一下split函数,通过括号内的条件切割字符串,不会显示条件包含的字符
        'x##'.split(/#/y)	  ==>['x##']    //从首位置开始查找,第一个字符为x,不匹配,直接将整个字符串返回
        '##x'.split(/#/y)	  ==>['','','x']   //首位置开始查找,匹配成功,切割,返回一个空字符串'',之后同理.
        //当然,这种方式后续分隔符必须紧跟前面才会被识别
        '#x#'.split(/#/y)   ==>['','x#']
      
    • 与y修饰符相匹配,ES6的正则对象多了sticky属性,表示是否设置了y修饰符,具体不作演示,正则表达式调用即可

  3. s修饰符(dotAll模式)

    • 正则表达式中 .修饰符可以代表任意的单个字符,但是行终止符除外:/foo.bar/.test('foo\nbar')这段代码中,.修饰符无法正确匹配换行符\n,返回false
    • 为了解决这个问题,ES6中引入了s修饰符,使得.操作符可以真正的p匹配任意单个字符:/foo.bar/s.test('foo\nbar')这时就可以正确返回true
先行断言和后行断言
  1. 先行断言:x只有在y前面才能匹配,必须写成/x(?=y)/,例如:/\d+(?=%)/.exec('100% of US presidents have been male') // ["100"] 表示返回%前面的数字

  2. 后行断言:正好相反,x只有在y后面才能匹配,格式为(?<=y)x

     //使用后行断言进行字符串替换
     const reg = /(?<=\$)foo/g;
     '$foo %foo foo'.replace(reg, 'bar');   ==>'$bar %foo foo'  
     //可以看到上述字符串只替换了在$后面的foo
    
具名组匹配(使用圆括号()进行组匹配)
  1. 普通组匹配:

     const RE_DATE = /(\d{4})-(\d{2})-(\d{2})/;
     const matchObj = RE_DATE.exec('2019-03-06');
     const year = matchObj[1];      ==> 2019
     const month = matchObj[2];     ==> 03
     const day = matchObj[3];       ==> 06
     //上面代码中,正则表达式里有三组圆括号,使用exec方法就可以将这三组匹配结果提取出来,类似于数组的各部分
     //这样的形式虽然也可以,但是每一组的具体含义不得而知,而且如果组的顺序改变的话,引用的时候就必须修改序号,因此会引入具名组匹配
    
  2. 具名组匹配:

     const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
     const matchObj = RE_DATE.exec('1999-12-31');
     const year = matchObj.groups.year; // 1999
     const month = matchObj.groups.month; // 12
     const day = matchObj.groups.day; // 31
     //可以看到两者的区别就是具名组匹配通过?<name>添加了具体的组名,这样就可以通过具体的组名来调用了,而且无需在意顺序问题,而且使用序号调用依然有效
     //如果没有可以匹配的组名,则返回undefined
    

关于正则表达式的问题,大致就这么多,还有一些基础的零散的知识没有具体列出来,希望对大家有帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值