date1108正则表达式

101 阅读8分钟

正则表达式详解

一、正则的概念

1.概念:规则表达式,我们来书写一段规则,用于匹配一段字符串是否符合规则。

2.创建两种方式:

  • 字面量的形式:const 变量 = /字符串内容/;
  • 内置构造函数:const 变量 = new RegExp(字符串内容);
        // 字面量的形式创建
        let reg = /abc/;

        // 以内置构造函数的形式创建
        let reg1 = new RegExp('!@#abc');

        // 答应结果:/abc/ /!@#abc/
        console.log(reg , reg1);

二、正则的常用方法

1.有两种常用方法:

  • 匹配:test
    • 语法形式:正则表达式.test(字符串);
    • 规范:如果符合就返回true,如果不符合规范就返回false。
  • 捕获:exec
    • 语法形式:正则表达式.exec(字符串);
    • 规范:如果符合就返回数组,如果不符合规范就返回null。
        // 定义一个正则表达式
        let reg = /abc/;

        let str = '111111111111';

        let str1 = 'abcabc';

        // 判断字符串形式是否符合正则表达式
        // 第一种写法
        console.log(reg.test(str));         // false
        console.log(reg.test(str1));        // true

        // 第二种写法
        console.log(reg.test('abcabc'));    // true

        // 第三中写法
        console.log(/abc/.test('1234'));    // false

三、元字符

1.正则表达式的符号有哪些组成?

  • 元字符:正则表达式的规则符号。
  • 修饰符:修饰整个正则表达式符号。

2.元字符 - 普通元字符

  • \d:
    表示一位数字(0-9).
  • \D:
    表示一位非数字(0-9).
  • \w:
    表示数字(0-9)字母(a-zA-Z)下划线(_)其中一个.
  • \W:
    表示除了数字(0-9)字母(a-zA-Z)下划线(_)这些字符的某一个字符.
  • \s:
    表示一位空白字符.
  • \S:
    表示一位非空白字符.
  • . :
    表示一位非换行的任意字符.
  • \ :
    表示转义符把有意义的符号转为有意义的文本,将没有意义的文本转为有意义的符号.
        // \d  匹配字符串有一位数字
        let reg = /\d/;
        console.log(reg.test('123455'));        // true
        console.log(reg.test('1aqaqaq'));       // true
        console.log(reg.test('aaaaaa'));        //false


        // \D 匹配字符串有一位非数字
        let reg1 = /\D/;
        console.log(reg1.test('a123'));         // true
        console.log(reg1.test('acacac'));       // true
        console.log(reg1.test('1242535'));      // false
        

        // \w  匹配字符串内容是否有一位数字字母下划线符合正则表达式
        let reg2 = /\w/;
        console.log(reg2.test('abc'));              // true
        console.log(reg2.test('abc123'));           // true
        console.log(reg2.test('!@#'));              // false
        console.log(reg2.test('!@#123'));           // true
        console.log(reg2.test('abc!@#123'));        // true
        

        // \W  匹配字符串内容是否除了有一位数字字母下划线符合正则表达式
        let reg2 = /\W/;
        console.log(reg2.test('abc'));             // false
        console.log(reg2.test('abc123'));          // false
        console.log(reg2.test('!@#'));             // true
        console.log(reg2.test('!@#123'));          // true
        console.log(reg2.test('abc!@#123'));       // true

    
        // \s  匹配字符串内容是否有空白字符符合正则表达式
        const reg = /\s/;
        console.log(reg.test('a'));               // false
        console.log(reg.test('ab'));              // false
        console.log(reg.test('a b'));             // true
        console.log(reg.test(' '));               // true


        // \S 匹配字符串没有空白字符符合正则表达式
        let reg = /\S/;
        console.log(reg.test(' '));              // false
        console.log(reg.test('a'));              // true
        console.log(reg.test(' b'));             // true


        // . 匹配有非换行的任意字符符合正则表达式
        let reg = /./;
        console.log(reg.test('\n'));            // false
        console.log(reg.test('/n'));            // true
        console.log(reg.test('111\n'));         // true
        console.log(reg.test('\nqw'));          // true


        // \.  匹配有.的字符串内容出现
        let reg = /\./;
        console.log(reg.test('\.'));                // true
        console.log(reg.test('/n'));                // false
        console.log(reg.test('/.n'));               // true
        console.log(reg.test('111\n'));             // false
        console.log(reg.test('1.00'));              // true

四、边界元字符

正则的边界元字符有两种:

1.^ 表示开头

2.$ 表示结尾

        // 字符串内容有数字符合正则表达式
        let reg1 = /\d/;
        console.log(reg1.test('123abc'));       // true
        console.log(reg1.test('1'));            // true
        console.log(reg1.test('abc123'));       // true


        // 字符串开头符合正则表达式
        let reg2 = /^\d/;
        console.log(reg2.test('123abc'));       // true
        console.log(reg2.test('1'));            // true
        console.log(reg2.test('abc123'));       // false


        // 字符串结尾符合正则表达式
        let reg3 = /\d$/;
        console.log(reg3.test('123abc'));       // false
        console.log(reg3.test('1'));            // true
        console.log(reg3.test('abc123'));       // true


        // 字符串开头和结尾有一个是数字符合正则表达式
        const reg4 = /^\d$/;
        console.log(reg4.test('123abc'));       // false
        console.log(reg4.test('1'));            // true
        console.log(reg4.test('abc123'));       // false

五、限定元字符

概念:表示前面一个符号出现了多少次。

1.*

  • 表示0~正无穷次

2.+

  • 表示1~正无穷次
  • 表示0~1次
  1. {n}
  • 表示限定n次 不能多也不能少
  1. {n,}
  • 表示最少n次
  1. {n,m}
  • 表示最少n次 最多m次
        // *  表示0~正无穷大
        let reg1 = /^\d*$/;
        console.log(reg1.test('abc'));      // false
        console.log(reg1.test('123'));      // true


        // +  表示1~正无穷大
        let reg1 = /^\d+$/;
        console.log(reg1.test('abc'));          // false
        console.log(reg1.test('1abc'));         // false
        console.log(reg1.test('1abc1'));        // false
        console.log(reg1.test('111'));          // true


        // ? 表示0~1次
        let reg1 = /^\d?$/;
        console.log(reg1.test('1'));            // true
        console.log(reg1.test('a'));            // false
        console.log(reg1.test(' '));            // false


        // {n}  表示只能出现n次
        let reg1 = /^\d{3}$/;
        console.log(reg1.test(123));                // true
        console.log(reg1.test('abc'));              // false
        console.log(reg1.test('12'));               // false



        // {n,}  表示能出现n次到无穷大
        let reg1 = /^\d{3,}$/;
        console.log(reg1.test(123));                // true
        console.log(reg1.test(123456));             // true
        console.log(reg1.test(12344688));           // true
        console.log(reg1.test('abc'));              // false
        console.log(reg1.test('12'));               // false



        // {n,m}  表示只能出现n次到m
        let reg1 = /^\d{3,5}$/;
        console.log(reg1.test(123));                // true
        console.log(reg1.test(12345));              // true
        console.log(reg1.test(12344688));           // false
        console.log(reg1.test('abc'));              // false
        console.log(reg1.test('abc123'));           // false

六、特殊元字符

正则的特殊元字符:

1.( )

  • 含义1:当成一个整体;eg:(abc)把abc当成一个整体
  • 含义2:到哪儿都捕获

2.|

  • 含义:或
  • eg:a|b 字符a或者字符b都行

3.[ ]

  • 含义:包含
  • 注意:[abcd]包含其中一位即可,[ ]实际代表的就是一位字符

4.[^]

  • 含义:非
  • 注意:[^abcd]只要不是他们四个中的一个即可,[^]实际代表的就是一位字符

5.-

  • 含义:到(至)只能在这个范围中的一个
  • 注意:通常包含[ ]和非^一起使用
  • eg:[^0-9]表示不是0到9中的一个即可
        // ()       包含整体
        let reg = /^(abc)$/;
        let reg1 = /^(abc){3}$/;
        console.log(reg.test('abc'));               // true
        console.log(reg.test('abcabc'));            // false
        console.log(reg.test('abcbc'));             // false
        console.log(reg1.test('abcabcabc'));        // true


        // |  或
        let reg = /^(abc|def)$/;
        let reg1 = /^(abc|def){2}$/;
        console.log(reg.test('abc'));               // true
        console.log(reg.test('abcabc'));            // false
        console.log(reg.test('abcbc'));             // false
        console.log(reg1.test('abcabc'));           // true
        console.log(reg1.test('abcdef'));           // true
        console.log(reg1.test('defdef'));           // true


        // []  包含其中一个
        let reg1 = /^[abcdef]$/;
        console.log(reg1.test('a'));                 // true
        console.log(reg1.test('b'));                 // true
        console.log(reg1.test('ab'));                // false
        console.log(reg1.test('!@#'));               // false


        // [^]      除了他们其中的任意一个字符
        let reg1 = /^[^abcdef]$/;
        console.log(reg1.test('a'));                 // false
        console.log(reg1.test('b'));                 // false
        console.log(reg1.test('ab'));                // false
        console.log(reg1.test('!'));                 // true
        console.log(reg1.test('!@#'));               // true


        // -   包含其中一个
        let reg1 = /^[a-f]$/;
        console.log(reg1.test('a'));                 // true
        console.log(reg1.test('b'));                 // true
        console.log(reg1.test('ab'));                // false
        console.log(reg1.test('!'));                 // false
        console.log(reg1.test('e'));                 // true

七、或的分界线区分

小练习

问题 :或(|)的分界线在哪里?答:或的分界线是小括号或者正则的边界(正则的尽头)

        // abc开头  def结尾
        let reg = /^abc|def$/;
        console.log(reg.test('abc123def'));     // true
        console.log(reg.test('abc12345'));      // true
        console.log(reg.test('12345def'));      // true
        console.log(reg.test('12345'));         // false


        console.log('-------------------------------------');


        // ab开头  ef结尾  cd中任选一个都行
        let reg1 = /^ab(c|d)ef$/;
        console.log(reg1.test('abcef'));        // true
        console.log(reg1.test('abdef'));        // true
        console.log(reg1.test('bdef'));         // false
        console.log(reg1.test('abde'));         // false
        console.log(reg1.test('acf'));          // false

八、正则的重复元字符

符号:\1 \2 .... \9 。eg:/(abc)\1/ 在abc的后面重复一个abc 打印出abcabc

eg:/(abc|def)\1/

解释:小括号内为abc \1这个位置也需要是abc;小括号内为def \1这个位置也需要是def。

        // \1重复字符
        let reg = /^(123|abc)\1$/;
        let reg1 = /^(123|abc){2}$/;
        console.log(reg.test(123123));      // true
        console.log(reg.test('123abc'));    // false
        console.log(reg.test('abcabc'));    // true
        console.log(reg1.test('123abc'));    // true


        // 标签判断
        let reg = /^<(p|span)><\/\1>$/;
        console.log(reg.test('<span></span>'));     // true
        console.log(reg.test('<p></p>'));           // true     
        console.log(reg.test('<p></span>'));        // false   
        console.log(reg.test('<span></p>'));        // false  

九、正则的标识符

正则的标识符

书写在正则的外边 用于描述整个正则表达式

  1. i 忽略大小写 eg:/\w/i

  2. g 全局判断 eg:/\w/g

        // i 忽略大小写  
        let reg1 = /^[a-q]$/i;
        console.log(reg1.test('A'));        // true
        console.log(reg1.test('BA'));       // false

十、正则表达式的捕获

语法:正则.exec(字符串);

  1. 没有捕获到 直接返回一个null
  2. 如果捕获到 直接返回一个数组
  • 2.1没有小括号也没有g的情况 永远捕获的都是开始下标0的第一个符合条件的内容

  • 2.2没有小括号 但是有修饰符g的情况

    • 第一次捕获完成后 第二次会从第一次捕获结束的位置开始
    • 第一次开始的时候 会从第二次捕获结束的时候开始
    • 当所有的匹配都匹配完成后 在捕获一次会返回一个null
    • 当两次捕获的时候 就从下标0重新开始
  • 2.3有小括号

    • 下标0还是我们正常捕获到的内容
        // 普通捕获
        let reg = /\d{3}/;
        console.log(reg.exec('abcabcabcdefdef'));       // null
        // 返回一个数组 捕获到下标为0的123
        console.log(reg.exec('abcabc123abca456bc'));       
        // 重复捕获 返回和上面一样
        console.log(reg.exec('abcabc123abca456bc'));    



        // g   全局捕获
        let reg1 = /\d{3}/g;
        console.log(reg1.exec('abcabcabcdefdef'));      // null
        console.log(reg1.exec('abcabc123abca456bc'));   // 123
        // console.log(reg1.exec('abcabc123abca456bc789'));     // 456
        // console.log(reg1.exec('abcabc123abca456bc789'));     // 789
        // console.log(reg1.exec('abcabc123abca456bc789'));     // null
        // console.log(reg1.exec('abcabc123abca456bc789'));     // 123
        
        

        // 有括号的时候
        // 从18位身份证中获取18位数字
        let reg2 = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/;
        let str = '我的身份证是522225200010031221';
        console.log(reg2.exec(str));

十一、课堂案例

将正则捕获到的值放置在数组中。

        let reg = /\d{3}/g;
        let str = 'a123xc456vb789nm000';
        const arr = [];
        // 这里定义为const  是常量 值不可以改变
        // let newArr = ;

        while (reg.exec(str) !== null) {

            arr.push(reg.exec(str)[0]);

            // newArr = reg.exec(str);
        }
        console.log(arr);

        /*
            将正则捕获到的值,放置在数组中
                代码处理后的arr === [123 , 456 , 789 , 000]
        */

十二、正则的两大特性

正则的两大特性

1.懒惰

  • 正常捕获字符串的时候 每次都从下标0开始
  • 解决方式:给正则添加一个修饰符g

2.贪婪

  • 每次在捕获的时候 会尽可能的多捕获一些东西
  • 解决:在原有的修饰符号后面添加一个?然后相当于开启非贪婪模式
  1. 贪婪能多拿就多拿

  2. 非贪婪能少拿就少拿

  3. 贪婪限定符:* + ? {n,} {n,m}

  4. 非贪婪限定符:*? +? ?? {n,}? {n,m}?

        // 贪婪模式
        // 把一整个都打印出来了
        // 获取的结果是一个数组的形式  但是内容是下面
        // 获取的结果是:<div><p>我是第一个p标签</p></div>
        let str = '<div><p>我是第一个p标签</p></div>';
        let reg = /<div.*>/;
        console.log(reg.exec(str));


        // 非贪婪模式
        // 也就是在*号后面直接添加一个? 就可以将贪婪模式转化成非贪婪模式
        // 获取的是一个数组的形式,其中的内容是:如下
        // 获取的结果是:<div>
        let str1 = '<div><p>我是第一个p标签</p></div>';
        let reg1 = /<div.*?>/;
        console.log(reg1.exec(str1));

十三、两种创建正则表达式的区别

        let reg = /\w/ig;
        console.log(reg);

        let reg1 = new RegExp('\\w' , 'ig');
        console.log(reg1);

        /*
            new RegExp('\w' , 'ig')

            会把'\w'   把w转化为以一个具有特殊含义的字符 所以这一步没有什么意义

            我们如果想要把正则表达式位\w    \\w
        */

十四、字符串的方法

字符串的方法(search; match; replace);

从字符串中查找是否满足正则的条件:

1.search

  • 语法形式:字符串.search(正则);
  • 返回值:如果找到,返回首次出现满足条件的下标;如果没找到就返回-1

2.match

  • 语法形式:字符串.match(正则);

  • 返回值:返回一个数组 数组下标0是第一个捕获到的值 重复捕获都是下标0的那个位置的值;没有捕获到返回一个null

  • 作用:当正则没有添加修饰符g的时候 作用类似于 正则.exec();如果添加了修饰符g,那么捕获到的以数组的形式返回满足条件的数值;没有捕获到的时候返回一个null

3.replace

  • 语法形式:字符串.relpace(正则 , 要替换的字符);
  • 作用:通过正则找到对应的字符 将其替换掉
        // search方法
        let reg = /\d{3}/;
        let str1 = '你好在吗123在的456';
        let str2 = '你好';
        console.log(str1.search(reg));      // 返回4
        console.log(str2.search(reg));      // 返回-1



        // match方法
        // 没有修饰符g的时候
        let reg1 = /\d{3}/;
        let str3 = '你好在吗123在的456';
        let str4 = '你好';
        console.log(str3.match(reg1));      // 返回一个数组 下标0的位置是满足条件的第一个数值
        console.log(str3.match(reg1));      // 返回一个数组 还是从下标0的位置开始满足条件的第一个数值
        console.log(str4.match(reg1));      // null

        // 有修饰符g的时候
        let reg2 = /\d{3}/g;
        let str5 = '你好在吗123在的456';
        let str6 = '你好';
        console.log(str5.match(reg2));      // 返回一个数组 数组里面是满足条件的数值
        console.log(str6.match(reg2));      // 返回一个null



        // replace方法
        let reg3 = /\d{3}/;
        let reg4 = /\d{3}/g;
        let str7 = '你好在吗123在的456';
        let str8 = '你好';
        console.log(str7.replace(reg3 , '*'));    // 返回值:你好在吗*在的456
        console.log(str7.replace(reg4 , '***'));    // 返回值:你好在吗***在的***
        console.log(str8.replace(reg4 , '*'));    // 返回值:你好