RegExp

概念:处理字符串的规则
扩展学习:console.dir(RegExp.prototype);

作用

  • [ ] (匹配)判断字符串是否规则
1
reg.test(str);//true\false
  • [ ] (捕获)捕获符合规则的内容
1
reg.exec(str);//["**",index:0,input:"***"]

创建方式

Object,Array两种方式没什么区别,但正则这两种方式有区别

1
2
var reg=/\d/;//字面量
var reg=new RegExp("");//实例
  • [x] 区别
    • [ ] 字符拼接
      • 字面量方式中,出现的都是元字符,不可进行变量拼接
      • 实例可以拼接(使用变量需要使用实例的创建方式
    • [ ] 字面量直接写\d,而实例中需转移\d;
1
2
3
4
5
6
var name="nic";
var reg=/^\d+"+name+"\d+$/g;
reg.test('2015"""nameee"2016');//true(两边必须是单引号,区别中间的双引号)
var reg=new RegExp("^\\d+"+name+"\\d+$","g");
reg.test("2015nic2016");//true

元字符

  • [x] 特殊意义的元字符

    • 1 \ 转义; 把有特殊意义的字符转换成原来自己的本意
      • 2 ^ 以什么开始 不占用位数
      • 3 $ 以什么结束 不占用位数
        • 只要用^$包含,那么字符串的位数和正则位数也要相等,否则就是false
    • 4 \n 换行
    • 5 . 除了\n以外的任意字符

      1
      2
      var reg=/^0.2$/;//以0开头,2结尾,中间任意字符(除了换行)
      var reg=/^0\.2$/;//0.2
      • 6 () 分组:大正则划分为几个小正则

        • 作用:改变x|y默认的优先级
        1
        2
        var reg= /^18|19$/;//(以1开头或以9结束)(以18开头或以19结束)18,19,189,181,119,819,1819……
        var reg= /^(18|19)$/;//18,19
      • 7 x|y x或y

      • 8 [xyz] x或y或z
      • 9 [^xyz] 除了它们中的任何字符
      • 10 [a-z] a-z的任何字符
  • 11 \d 代表0-9之间的任意数字
  • 12 \w 代表 [0-9a-zA-Z _] 数字,字母,下划线
  • 13 \D 除了0-9
  • 14 \W 除了\w

  • 15 \b 边界 不占位 “w1 w2 w3”每个单词两边都是边界

  • 16 \s 空格空白等
  • [x] 次数的量词元字符
    • 1 * 出现0到多次
    • 2 + 出现1到多次
    • 3 ? 出现0到1次 ==> 要么出现要么不出现
    • 4 {n} 只能出现n次
    • 5 {n,} 至少出现n次
    • 6 {n,m} 至少出现n次最多出现m次

元字符应用

  • [x] []中出现的字符都是本身意思
  • [x] []不识别两位数字

    • [ ] 有效数字的正则(正、负、小数、0)

      • 开头+ —可有可无
      • 多位不能以0开头
      • . 一旦出现后必跟数字

        1
        var reg=/^[+-]?(\d|([1-9]\d+))(\.\d+)?$/;
        1
        2
        var reg=/^[12]$/;//->1、2
        var reg=/^[12-68]$/;//->1、2-6、8
    • [ ] 年龄介于18-65间,18-19 20-59 60-65

      1
      reg=/^(1[89]|[2-5]\d|6[0-5])$/;
- [ ] 简单邮箱 

    
1
var reg = /^[\w.]+@[0-9a-zA-Z]{2,20}(\.[a-zA-Z]{2,4}){1,2}$/;
- [ ] 2-4位汉字
1
var reg = /^[\u4e00-\u9fa5]{2,4}$/;
- [ ] 身份证
1
2
//var reg = /^\d{17}(\d|X)$/;
var reg=/^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X)$/

正则捕获

  • [x] 知识点

    • [ ] exec:内容是数组,捕获不成功则结果null

      • [ ] exec和match优缺点
        • exec:(分组捕获时)能够捕获大正则和小正则
        • match:一次可获取所有捕获内容(只捕获大正则)
    • [ ] ?在正则中作用

      • 1 普通元字符后,修饰前面的元字符出现0-1次/\d?/
      • 2 量词后,每次尽可能少的去匹配/\d+?/
      • 3 匹配不捕获: “?:” 在分组中,分组括号的前面(?:\d{2}), 仅仅是匹配作用。不会捕获分组里面的内容
        1
        2
        3
        4
        5
        var reg=/^(?:\d{2})(\d{2})(\d{2})(\d)(\d|X)$/;
        var str="43 44 22 3 3";
        var get=reg.exec(str);
        get[0];//->大正则;
        get[1];//->44 小正则;
  • [x] 正则中exec方法(只捕获1个)

    • [ ] 懒惰性: 每次执行exec只捕获第一个匹配的内容;

      1
      2
      3
      4
      5
      var str = "zh2015p2016";
      var reg = /\d+/;//加g解决
      reg.exec(str);//->["2015",index:2,input:"zh2015p2016"]
      reg.exec(str);//->["2015",index:2,input:"zh2015p2016"]

      加个g可以解决此问题

      1
      2
      3
      4
      5
      var str = "zh2015p2016";
      var reg = /\d+/g;
      reg.exec(str);//->["2015",index:2,input:"zh2015p2016"]
      reg.exec(str);//->["2016",index:2,input:"zh2015p2016"]
    • [ ] 贪婪性: 每次尽可能多去匹配。

      1
      2
      3
      var str = "z2017p2018z2019";
      var reg = /\d+/g;
      reg.exec(str);//["2015"……],2符合20也符合,只匹配最长的2015

      就在量词后面加”?”解决此问题

      1
      2
      3
      var str = "z2017p2018z2019";
      var reg = /\d+?/g;
      reg.exec(str);//["2"……]
    • [ ] 怎么捕获所有内容

      1
      2
      3
      4
      5
      6
      7
      8
      9
      var str = "z2017p2018z2019";
      var reg = /\d+/g;
      var ary = [];
      var res = reg.exec(str); //[2017,index,input] 不是null ==> 没有捕获到尾,那需要继续捕获
      while(res){
      ary.push(res[0]);
      res = reg.exec(str); //给res重新赋值,变换while的条件,继续向后查找,如果能找到那么就返回一个新的数组。res现在会代表一个新的数组。如果不能找到那么res就是null
      }
      console.log(ary);
  • [x] 字符串中match(捕获所有)

    1
    2
    3
    4
    5
    var str = "z2017p2018z2019";
    var reg = /\d+?/g;
    str.match(reg);//["2", "0", "1", "7", "2", "0", "1", "8", "2", "0", "1", "9"]
    var reg = /\d+/g;//["2017", "2018", "2019"]
    var reg = /\d+/;//["2017"]

正则分组

  • [x] 1、改变优先级
  • [x] 2、分组引用

    • [ ] \2代表第二个分组一样的内容

      1
      2
      var reg=/^(\w)\1(\w)\2$/;
      reg.test("zzff");->true
  • [x] 3、分组捕获(大小正则都捕获)

    1
    2
    3
    4
    5
    var reg=/^(\d{2})(\d{4})(\d{4})(?:\d{2})(\d{2})(\d{2})(\d)(\d|X)$/;
    var str="12 3232 4343 43 44 22 3 3";
    var get=reg.exec(str);
    get[0];//->大正则;
    get[1];//->44 小正则;
  • [ ] exec和match优缺点

    • exec:(分组捕获时)能够捕获大正则和小正则
    • match:一次可获取所有捕获内容(只捕获大正则)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      var reg=/^zz(\d+)$/g;
      var str="zz12zz34zz56";
      //exec
      reg.exec(str);//->["zz12", "12"]
      reg.exec(str);//->["zz34", "34"]
      reg.exec(str);//->["zz56", "56"]
      //match
      str.exec(reg);//->["zz12", "zz34", "zz56"]

正则解决replace无法替换多个字符的问题

  • [ ] replace用正则的原理
1
2
3
4
5
6
7
8
9
var str = "zh2015zh2016";
str = str.replace(/zh/g,function (){//匿名函数执行多少次取决于正则字符串捕获多少次
console.log(arguments); //和正则reg.exec捕获来的结果是一样的
return 1;//返回的1,替换了每一次大正则捕获的内容
});
//arguments[0]:大正则捕获的内容
//第一次执行的arguments:["zh", 0, "zh2015zh2016"]
//第二次执行的arguments:["zh", 6, "zh2015zh2016"]
//RegExp.$1->第一分组内容
  • [ ] 实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var ary = ["零","壹","贰","叁","肆","伍","陆","柒","捌","玖"];
    var str = "2015";
    str = str.replace( /(\d)/g , function (){
    var num=arguments[0];//大正则捕获的内容(函数执行四次分别为2、0、1、5)
    var str=ary[num]; //2索引到"贰"
    return str;
    //return ary[argument[0]];
    });