正则表达式(Regular Expression) 基础

449 阅读6分钟

正则表达式(Regular Expression)

主要知识点

​ 1)正则的创建

​ 2)正则的匹配方法

​ 3)元字符

​ 4)字符集合

​ 5)边界

​ 6)分组

​ 7)反向引用

​ 8)数量词汇

​ 9)匹配模式

正则在js中的使用

替换,查找,验证,分割

字符串操作

  • 查找字符串中的数字;

  • 正则如何如实现

    在一个字符串中提取数字

    let reg = /\d+/g;
    let arr =  str.match(reg);
    console.log(arr);
    

正则的创建

  • 字面量创建

      1.字面量创建
        let str = "abc1231dfaf123213fda";
        // let reg = /\d+/g;
        // let abc = "1231"
        let reg = /abc/g;
        let res = str.match(reg);
        console.log(res);
    
  • 通过构造函数

    转义字符要加\\d

    // 2.构造函数创建
    let str = "abc1231dfaf123213fda";
    // let reg = new RegExp("\\d+","g");
    let abc = "1231";
    let reg = new RegExp(abc,"g");
    let res = str.match(reg);
    console.log(res
    

正则的匹配方法

字符串方法

  • match

     let str = "abc11defghiej222k";
     let reg = /\d+/g;
     console.log( str.match(reg) );
    
  • search

    返回索引值,这个会忽略全局匹配。没有就返回-1

     let str = "abcdefghiejk";
     // let reg = /e/g;
     let reg = /z/;
     console.log( str.search(reg) );
    
  • replace

    敏感词过滤

    let str = "abc11defghiej222k";
    let reg = /\d/g;
    // console.log( str.replace(reg,"*") );
    
    //arg 匹配的字符,第二个参数是分组 ...参考mdn
    let res =  str.replace(reg,function(arg){
        console.log(arg)
        return "*"
    })
    console.log(res);
    
  • split

     let str = "abc123fda1234rt";
     // let arr =  str.split(1);
     let arr =  str.split(/\d+/);
    

正则对象下的方法

  • test 测试是否能匹配

  • exec 每次匹配成功一次然后停止,记录索引位置,然后再次调用的时候,会根据上次结束的位置进行匹配

    let str = "abc123fda123";
    // let reg = /\d+/g;
    let reg = /efg/g;
    console.log( reg.test(str) );
    let str = "abc123fda1234";
    let reg = /\d+/g;
    
    console.log( reg.exec(str) )
    console.log(reg.lastIndex);
    console.log( reg.exec(str) )
    console.log( reg.exec(str) )
    

元字符

  • 正则表达式中有特殊含义的非字母字符;

​ 字符类别(Character Classes)

  • \

    • 转义符,它有两层含义
      • 表示下一个具有特殊含义的字符为字面值
      • 表示下一个字符具有特殊含义(转义后的结果是元字符内约定的)
  • 字符相关的元字符
    • \w 匹配任意一个(字母、数字、下划线)的字符
    • \W 匹配任意一个非(字母、数字、下划线)的字符
    • \s 匹配一个空白符,包括空格、制表符、换页符、换行符和其他 Unicode 空格
    • \S 匹配一个非空白符
    • \d 匹配任意一个阿拉伯数字的字符
    • \D 匹配任意一个非阿拉伯数字的字符
    • .
      • 匹配行结束符(\n 是回车 \r 是换行 \u2028 行分隔符 或 \u2029 段落分隔符)以外的任意单个字符都可以匹配到
      • 字符集合(Character Sets) 中,.将失去其特殊含义,表示的是原始值
  • 数量相关的
    • {}

      • x{n}

        • n 是一个正整数。前面的模式 x 连续出现 n 次时匹配
      • x{n,m}

        • n 和 m 为正整数。前面的模式 x 连续出现至少 n 次,至多 m 次时匹配
        • n~m次出现
      • x{n,}

        • n 是一个正整数。前面的模式 x 连续出现至少 n 次时匹配

           let str = "abceeeeeeeeeeeffd";
           // let reg = /ce{3}f/g;
           // let reg = /ce{1,4}f/g;
           // let reg = /ce{1,}f/g
           console.log( reg.test(str) );
          
    • x*

      • 匹配前面的模式 x 0 或多次
    • x+

      • 匹配前面的模式 x 1 或多次。等价于 {1,}
    • x?

      • 匹配前面的模式 x 0 或 1 次

        // ? --> {0,1}  + ---> {1,} * ---> {0,};
         let str = "my name is lilei";
         let reg = /my\s+name/g;
         console.log( reg.test(str));
        
        let str = "123456789";
        // let reg = /\d{2,4}/g;  //贪婪匹配
        let reg = /\d{2,4}?/g;   // 惰性匹配;
        let res =  str.match(reg);
        console.log(res)
        
    • x|y

      • 匹配 x 或 y
  • 位置相关
    • ^

      • 匹配输入开始。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符后的开始处
    • $

      • 匹配输入结尾。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符的前的结尾处

        let str = "abedef";
        let reg =/^\w/g;
        let res =  str.replace(reg,"*");
        console.log(res);
        
        
        let str = "abedef";
        let reg =/\w$/g;
        let res =  str.replace(reg,"*");
        console.log(res);
        
    • \b

      • 匹配一个零宽单词边界(zero-width word boundary)
    • \B

      • 匹配一个非零宽单词边界(zero-width word boundary)
    // 边界: 非\w 的 都是边界;
    let str = "this is a book";
    let reg = /\bis\b/g;
    let res =  str.match(reg);
    console.log(res);
    
    // \B 非边界;
    let str = "this is a book";
    let reg = /\B\w{2}\b/g;
    let res =  str.match(reg);
    console.log(res);
    

字符集合 []

[xyz]

  • 一个字符集合,也叫字符组。匹配集合中的任意一个字符。你可以使用连字符'-'指定一个范围

  • [xyz] 是一个反义或补充字符集,也叫反义字符组。也就是说,它匹配任意不在括号内的字符。你也可以通过使用连字符 '-' 指定一个范围内的字符

  • [^0-9] 表示非数字 这里面的^ 是非的意思

    // []:字符集合;
    let str = "My name is LiL1ei";
    // let reg = /Li[Ll]ei/g;
    // [a-z] [A-Z];  
    //[a-Z] 错误 askii 码来的
    // let reg = /[0-9]/g;
    // console.log( reg.test(str));
    let reg = /[^0-9]/g;
    console.log( reg.test(str));
    // \d == [0-9]; \w ==[a-zA-Z0-9_];
    

分组 () 括号相关

  • (子项)

    • 可以使用 () 对表达式进行分组,类似数学中分组,也称为子项

      let str = "abababfdsafds";
      let reg = /(ab){3}/g;
      console.log(reg.test(str));
      
    • 捕获匹配

      • 具有捕获(capturing)特性,即会把匹配结果保存到(子项结果)中

      • (x)

        let str = "2020-01-02";
        let reg = /(\d{4})-(\d{2})-(\d{2})/;
        // console.log(  );
        str.match(reg)
        console.log(RegExp.$1)
        console.log(RegExp.$2)
        console.log(RegExp.$3)
        
    • 替换值

      • //字面量
        let str = "2020-01-02"; // 01/02/2020
        let reg = /(\d{4})-(\d{2})-(\d{2})/;
         let res =  str.replace(reg,"$2/$3/$1");
        
        //方法
         let res =  str.replace(reg,function(arg,year,mouth,date){
             return mouth +"/" + date + "/" +year;
         });
        
    • 反向引用 \n

      有时候前面匹配到的规则,后面也要使用

      • 这里的 n 表示的是一个变量,值为一个数字,指向正则表达式中第 n 个括号(从左开始数)中匹配的子字符串

      •  let className = "news-container-nav"; //news_container_nav
        // \n 在\1 哪里,表示匹配第一个分组就是 (-|_)
         let reg = /\w{4}(-|_)\w{9}(\1)\w{3}/;
         let res =  reg.test(className);
         console.log(res);
        
    • 索引分组

    • 命名分组

      • (?...) 名字

      • groups属性 下面有命名的分组

        let str = "2020-01-06";
        let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
        console.log( str.match(reg));
        
    • 非捕获匹配

      • 不具有捕获(capturing)特性,即不会把匹配结果保存到(子项结果)中
      • (?:x)
    • 零宽断言/预查(Assertions)

      • 用于指定查找在某些内容(但并不包括这些内容)之前或之后的内容
      • 正向零宽断言/预查
        • 肯定
          • (?=pattern)
        • 否定
          • (?!pattern)
      • 负向零宽断言/预查(注意:ES2018新增)
        • 肯定
          • (?<=pattern)
        • 否定
          • (?<!patten)
    • 捕获与零宽断言的区别

      • 捕获:匹配的内容出现在结果中但不出现在子项结果中
      • 零宽断言:完全不会出现在结果
      正向零宽断言;替换前面的iphone
      let str = "iphone3iphone4iphone5iphonenumber";
      // 肯定
      // let reg = /iphone(?=\d)/g;
      // 否定
      let reg = /iphone(?!\d)/g;
      let res = str.replace(reg,"苹果");
      console.log(res);
      
      
      // 负向零宽断言;替换后面的px
      let str = '10px20px30pxipx';
      // 肯定
      // let reg = /(?<=\d+)px/g;
      // 否定
      let reg = /(?<!\d+)px/g;
      let res =  str.replace(reg,"像素");
      console.log(res);
      

    匹配模式

    • g

      • global,全局模式:找到所有匹配,而不是在第一个匹配后停止
    • i

      • ignore,忽略大小写模式:匹配不区分大小写
    • m

      • multiple,多行模式:将开始和结束字符(^和$)视为在多行上工作,而不只是匹配整个输入字符串的最开始和最末尾处

      • let str = `abc
        efg
        hij`;
        let reg = /^\w/gm;
        let res =  str.replace(reg,"*");
        console.log(res);
        
    • s

      • dotAll / singleline模式:. 可以匹配换行符

        s : 让"."let str = `abc
        efg`;
        let reg = /^a.*g$/gs;
        console.log( reg.test(str));
        
    • u

      • unicode,unicode模式:匹配unicode字符集

      • {}表示unicode编码

        let str = "a";
        let reg = /\u{61}/gu;
        console.log(reg.test(str));
        
    • y

      • sticky,粘性模式:匹配正则中lastIndex属性指定位置的字符,并且如果没有匹配也不尝试从任何后续的索引中进行匹配

      • 必须连续匹配。不然就匹配不到

        let str = "12345fdafdsa4324";
        let reg = /\d/gy;
        //4324 匹配不到了
        console.log( reg.exec(str));
        console.log( reg.exec(str));
        console.log( reg.exec(str));
        console.log( reg.exec(str));
        console.log( reg.exec(str));
        console.log( reg.exec(str));