正则表达式

194 阅读2分钟

1.1-正则表达式介绍

  • 本小节知识点

    • 1.什么是正则表达式

      • 正则表达式是一个用于对字符串实现逻辑匹配运算的对象
    • 2.正则表达式的作用

      • 按照某种规则来匹配字符串,而正则表达式就是制定这个规则
    • 3.如何使用正则表达式

      • (1)创建正则表达式对象
      • (2)开始匹配 使用test()方法
    • 4.正则表达式特点

      • 对初学者极度的不友好
      • 非常的晦涩难懂
    • 5.学习目标

      • 1.可以使用正则表达式验证常用表单文本(手机、邮箱、qq、座机、姓名)
      • 2.了解正则表达式在开发中的一些应用场景
  • 正则表达式图形化网站:regexper.com/

    • 正则表达式非常的晦涩难懂,使用图形可以更好的方便理解,正所谓一图胜千言
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
        /* 
        1.正则表达式 :RegExp (regular expression)  是ECMAScript内置对象
        2.作用 :对 字符串进行逻辑匹配 运算
        3.使用流程 :
            (1)创建正则对象 :  new RegExp(/正则表达式/);
            (2)test('字符串') : 对字符串进行逻辑匹配运算
        */
​
        /* 
        1.正则表达式 :是一个对 字符串进行逻辑匹配运算 的对象
            a. 正则是内置对象 : 存储一些属性和方法
            b. 表达式 :  对字符串 进行逻辑匹配 运算
        
        2.使用流程 :两个步骤
        */
​
        //(1)调用构造函数,创建正则对象
        let reg =  new RegExp(/a/);
​
        //(2)调用test方法,对字符串进行运算   true:符合规则   false:不符合
        console.log(  reg.test('abcdefg') );
        console.log(  reg.test('123456') );
​
​
        /* 了解: 正则表达式字面量写法  /正则表达式/ */
​
        console.log(  /a/.test('我爱你') );//false
    </script>
</body>
</html>

1.2-元字符与原义文本字符

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
        /* 
        一个正则表达式主要由两部分组成
            1.原义文本字符 : 就是字符本身的含义,千万别想多了
            2.元字符 : 改变了字符串本身的含义 (相当于js的关键字)
                . \ | [] {} () + ? * $ ^
        */    
        
       
        //1.原义文本字符 : 就是字符本身的含义,千万别想多了
        /*  /abc/ :  含义,就是检查字符串中有没有abc。 别想多了
                不是说有a或者有b或者有c,也不是说有a 和 b 和 c
        */
​
        console.log(/abc/.test('a123'));//false
        console.log(/abc/.test('ab123c'));//false
        console.log(/abc/.test('abc123'));//true
​
        console.log(/黑马/.test('绿裙很黑'));//false
        console.log(/黑马/.test('一匹黑色的马'));//false
        console.log(/黑马/.test('黑马程序员,程序员的王者'));//true
        
    
    </script>
</body>
</html>

1.3-字符类

//1.一般情况下,正则表达式的一个字符就是对于字符串的一个字符,这样处理比较方便
    //例如:  /abc/  : 含义就是匹配字符串 `abc`
​
    //2.有时候我们并不想只匹配一个字符,而是想要匹配符合某一类特征的字符,这时就可以使用字符类
​
    /*2.创建简单字符类:  []
        * 这里类指的是符合某些特征的对象,只是一个泛指,而不是指某个字符
        * 例如正则表达式:  /[abc]/ :把字符a或b或c归为一类,可以匹配这类的字符
        * /[abc]/ : 含义是,匹配字符串中只要有 a或者b或者c任何一个即可
     */
    console.log ( /[abc]/.test ( "eeeeeeeffffffffff" ) );//false
    console.log ( /[abc]/.test ( "eaeeeeeeffffffffff" ) );//true
    console.log ( /[abc]/.test ( "ebeeeeeeffffffffff" ) );//true
    console.log ( /[abc]/.test ( "eceeeeeeffffffffff" ) );//true
​
    /*3.反向类(负向类): ^
        * 反向类意思是不属于某类的内容
        * 例如正则表达式: [^abc] :含意是,不是字符a或b或c的内容
     */
    //只要有任何一个字符不是a或者b或者c,就满足条件
    console.log ( /[^abc]/.test ( "1abacbc" ) );//true
    console.log ( /[^abc]/.test ( "aaaabbbbccccc" ) );//false
    console.log ( /[^abc]/.test ( "aaaabbbbccccce" ) );//true

1.4-范围类

//需求:使用字符类匹配数字
    // 正则表达式: [0123456789] : 含义是,有任何数字的内容
    //弊端:表达式冗余,假如我要匹配字母,那就要写 [abcdefg...........xyz],非常麻烦
    //如何解决冗余问题? ——使用范围类
    console.log ( /[0123456789]/.test ( "1avcsvs" ) );//true
    console.log ( /[0123456789]/.test ( "aaaaa" ) );//false
​
    /*1.范围类:   -
         [0-9] : 含义是, 0-9之间的任意字符
         [a-z]: 含义是,a-z之间的任意字符
         [A-Z]:含义是,A-Z之间的任意字符
     * 注意点
        a.范围类是一个闭区间,  [a-z],这个范围包含字符a和z本身
        b.在[]内部是可以连写的, [0-9a-zA-Z] : 含义是,包含数字0-9,或者a-z,或者A-Z任意字符
        c. -右边一定要大于左边,例如 [5-8],这是合法的表示5-8之间的数字,不能写[8-5],程序会报错(正则语法错误)
     */
​
    //示例1
    console.log ( /[0-9]/.test ( "1acasdas" ) );//true  只要有数字就满足
    console.log ( /[0-9]/.test ( "acasdas" ) );//false
    //示例2
    console.log ( /[a-z]/.test ( "a6666ABC" ) );//true  只要有任何小写字母就满足
    console.log ( /[a-z]/.test ( "6666ABC" ) );//false
    //示例3
    console.log ( /[A-Z]/.test ( "Aa6666" ) );//true  只要有任何大写字母就满足
    console.log ( /[A-Z]/.test ( "a6666" ) );//false
    //示例4
    console.log ( /[0-9a-zA-Z]/.test ( "a.........[][]]" ) );//true  只要有任何字母字符或数字字符就满足
    console.log ( /[0-9a-zA-Z]/.test ( "+-*/......[]" ) );//false
    //示例5: 匹配数字 0-9 范围字符 或 - 字符
    //解决方案:在最后面写上 -
    console.log ( /[0-9-]/.test ( "-abcdefh" ) );//

1.5-预定义类

/*预定义类: 正则表达式提供好的用来匹配常见的字符类
         预定义类           等价类                                     含义
             .                 [^\r\n]                         除了回车和换行之外的所有字符
           \d                 [0-9]                           数字字符
           \D                 [^0-9]                         非数字字符
           \s                 [\f\n\r\t\v]                    空白字符
           \S                 [^\f\n\r\t\v]                  非空白字符
           \w                 [a-zA-Z_0-9]                单词字符(字母、下划线、数字)
           \W                 [^a-zA-Z_0-9]              非单词字符
     */
​
    //1.  . 除了回车和换行之外的所有字符
    console.log ( /./.test ( "\r\n" ) );//false
    console.log ( /./.test ( "" ) );//false 空字符
    console.log ( /./.test ( " " ) );//true 空格字符
    console.log ( /./.test ( "\t爱你么么哒" ) );//true
​
    //2. \d   数字字符(只要有数字即可)
    console.log ( /\d/.test ( "123abc" ) );//true
    console.log ( /\d/.test ( "abc" ) );//false
​
    //3. \D  非数字字符(只要没有数字即可)
    console.log ( /\D/.test ( "123abc" ) );//true
    console.log ( /\D/.test ( "123" ) );//false
​
    //4.  \s   空白字符(只要有空白字符即可)
    console.log ( /\s/.test ( "\nabc" ) );//true
    console.log ( /\s/.test ( "abc" ) );//false
​
    //5.  \S  非空白字符(只要有非空白字符即可)
    console.log ( /\S/.test ( "\nabc" ) );//true
    console.log ( /\S/.test ( "abc" ) );//true
    console.log ( /\S/.test ( "" ) );//false
    console.log ( /\S/.test ( "\t\n" ) );//false
​
    //6  \w  单词字符(只要有字母、数字、下划线即可)
    console.log ( /\w/.test ( "abc123_中国" ) );//true
    console.log ( /\w/.test ( "中国" ) );//false
​
    //7  \W 非单词字符(只要有除字母、数字、下划线之外的任意字符即可)
    console.log ( /\W/.test ( "abc123_中国" ) );//true
    console.log ( /\W/.test ( "中国" ) );//true
    console.log ( /\W/.test ( "abc123_" ) );//false

1.6-边界

  • 严格匹配: ^字符串$

    • 例如: ^abc$ : 含义是,字符串必须以a开头,中间必须是b,结尾必须是c

      • 满足该条件的只有一个字符串: abc

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <script>
      /*正则表达式元字符含义可能不止一种,会有多种含义。 (类似于js的 + )
        
        /abc/ : 原义文本字符。 检测字符串有没有abc 
        /[abc]/ : 字符类。 检测字符串是否有 a或b或c 其中之一。
        /[^abc]/ : 反向类。 检测字符串是否有 不是a或 不是b或 不是c 任意字符。
            ^ 写在 [] 里面就是反向类
        /^abc/ : 开头边界。 检测字符串是不是a开头
            ^ 单独使用就是开头边界。 边界不是检测字符串,而是检测位置的。
        */
​
      /*边界:正则表达式提供了几个常用的边界匹配字符
            边界字符            含义
                ^               以xxxx开头
                $               以xxxx结束
        */
​
      //1.  开头边界,以xxx开头
      /*   
        /^abc/ 
            正确含义:  a(开头) + bc(a的后面一定要是bc)
            错误含义: 以abc开头 (虽然这个正则表面上必须是前面是abc的才符合,但是这个正则就不能理解为以abc开头)
        */
​
      console.log(/^abc/.test('a123abcabc')) //false
      console.log(/^abc/.test('a1b1c1')) //false
      console.log(/^abc/.test('abcabc')) //true
​
      //2. 结尾边界,以xxx结尾
      /* 
        /abc$/
            正确含义: ab + c(c结尾位置,前面是ab)
            错误含义: 以abc结尾(虽然这个正则表面上必须是abc在结尾位置才符合,但是这个正则就不能理解为以abc结尾)
      
      */
      console.log(/abc$/.test('a123abcabc')) //true
      console.log(/abc$/.test('ab123c')) //false
      console.log(/abc$/.test('abc123')) //false
      console.log(/abc$/.test('abcabc')) //true
​
      /*3.正则严格匹配 : 同时添加开头边界与结尾边界 
        /^abc$/ 
            正确含义: a(开头) + b + c(结尾)
                * 世界上只有唯一的一个字符满足条件:  abc
            错误含义: 以abc开头 且 以abc结尾的字符
      */
      console.log(/^abc$/.test('a123abcabc')) //false
      console.log(/^abc$/.test('ab123c')) //false
      console.log(/^abc$/.test('abc123')) //false
      console.log(/^abc$/.test('abcabc')) //false
      console.log(/^abc$/.test('abc')) //true
      
    </script>
  </body>
</html>

1.7-量词

/需求:匹配一个连续出现10次数字的字符
    //正则表达式:   /\d\d\d\d\d\d\d\d\d\d/
    //弊端:表达式冗余    解决方案:使用量词
    console.log ( /\d\d\d\d\d\d\d\d\d\d/.test ( "1234567abc" ) );//false
    console.log ( /\d\d\d\d\d\d\d\d\d\d/.test ( "1234567890abc" ) );//true
​
    /*量词: 表示字符出现的数量
​
    量词                  含义
    ?                       出现零次或一次(最多出现一次)
    +                       出现一次或多次(至少出现一次)
    *                       出现零次或多次(任意次)
    {n}                     出现n次
    {n,m}                  出现n-m次
    {n,}                     出现至少n次(>=n)
     */
​
    //需求:匹配一个连续出现10次数字的字符
    console.log ( /\d{10}/.test ( "1234567abc" ) );//false
    console.log ( /\d{10}/.test ( "1234567890abc" ) );//true

1.8-分组

/*1. ()   这个元字符有两个含义
            a.分组:使量词作用于分组
                * 量词只能作用于一个字符,如果想作用与多个字符,就要使用分组(将多个字符当成一组)
            b.提升优先级:通常与元字符 | 一起使用
      2. |   或
            * | 默认作用于两边的所有字符,如果只想作用与指定字符,则可以使用() 来提升优先级
     */
​
    //1. 需求: 匹配连续出现三次love的字符串
​
    //1.错误写法:  /love{3}/  , 含义: lov + e{3}
    console.log ( /love{3}/.test ( "lovelovelove" ) );//false
    console.log ( /love{3}/.test ( "loveee" ) );//true
    console.log ( /love{3}/.test ( "loveeeabc" ) );//true
    //2.正确做法:使用分组   /(love){3}/
    console.log ( /(love){3}/.test ( "lovelovelove" ) );//true
    console.log ( /(love){3}/.test ( "loveee" ) );//false
​
    //2. 需求:匹配 love 或者 live
    //1.错误写法:  /lo|ive/  ,含义:  lo  或者  ive
​
    console.log ( "I love you".replace ( /lo|ive/, "X" ) );// I Xve you
    console.log ( "I live you".replace ( /lo|ive/, "X" ) );// I lX you
​
    //2.正确写法: /l(o|i)ve/, 含义:匹配love 或者 live
​
    console.log ( "I love you".replace ( /l(o|i)ve/, "X" ) );// I X you
    console.log ( "I live you".replace ( /l(o|i)ve/, "X" ) );// I X you

1.9-修饰符

/*修饰符:影响整个正则规则的特殊符号
        书写位置:  /pattern/modifiers(修饰符)
        i (intensity):大小写不敏感(不区分大小写)
        g (global) : 全局匹配
     */
    //1.   i:不区分大小写
    var str = 'ABCabcdefgaaaAAA';
    console.log ( str.replace ( /a/, "X" ) );//ABCXbcdefgaaaAAA   //默认区分大小写
    console.log ( str.replace ( /a/i, "X" ) );//XBCabcdefgaaaAAA
​
    //2.  g:全局匹配
    var str = 'ABCabcdefgaaaAAA';
    console.log ( str.replace ( /a/, "X" ) );//ABCXbcdefgaaaAAA   //默认匹配第一个就停止
    console.log ( str.replace ( /a/g, "X" ) );//ABCXbcdefgXXXAAA   //默认匹配第一个就停止
    //修饰符可以同时使用多个
    console.log ( str.replace ( /a/ig, "X" ) );//XBCXbcdefgXXXXXX

-正则表达式test与exec方法介绍

//正则表达式对象RegExp有两个常用方法: test    exec
​
    /*1.RegExp.prototype.text(str)
    作用:检测参数str是否满足正则表达式的匹配规则
    返回值:true 可以匹配   false:不能匹配
     */
    //示例:检测一个字符串中有没有单词字符
    console.log ( /\w/.test ( "a" ) );//true
    console.log ( /\w/.test ( "=" ) );//false
​
    /*1.RegExp.prototype.exec(str)
    作用:查看正则表达式匹配str的结果(是第几个字符满足匹配规则的,是哪个字符满足匹配规则等)
    返回值:null(无法匹配)   或者  数组(存放匹配信息)
        返回值数组
            特点:默认情况下,每一次调用exec只会返回第一个匹配的字符串信息,如果想要返回所有匹配信息
                a.需要设置正则表达式为全局匹配
                b.需要执行多次exec方法
           属性介绍
                index:匹配字符的下标
                下标:0:匹配字符
                        1-n:后面的下标只对()分组有效,没有分组则数组只有一个元素
     */
​
    //示例1:找出第一个匹配字符中包含  数字+单词 + 单词字符的内容
    //默认:只能找到第一个匹配的字符
    var str = "1aasjdg2bbjahsgd3cc";
    var reg = /\d\w\w/;
    var resArr = reg.exec ( str );
    console.log ( resArr );//["1aa", index: 0, input: "1aasjdg2bbjahsgd3cc", groups: undefined]
​
    //示例2:找出所有匹配字符中包含   数字+单词 + 单词字符的内容
    var str = "1absjdg2cdjahsgd3ef";
    var reg = /\d\w\w/g;//需要设置全局匹配
​
    var resArr = reg.exec ( str );
    // console.log ( resArr );//["1ab", index: 0, input: "1absjdg2cdjahsgd3ef", groups: undefined]
    // //每一次匹配之后,reg会记录当前已经匹配的字符,下一次再执行exec的时候就会往后面匹配
    // resArr = reg.exec(str);
    // console.log ( resArr );//["2cd", index: 0, input: "1absjdg2cdjahsgd3ef", groups: undefined]
    // resArr = reg.exec(str);
    // console.log ( resArr );//["3ef", index: 0, input: "1absjdg2cdjahsgd3ef", groups: undefined]
​
    //以上代码可以简写成
    while(resArr){//只要resArr存在,就继续执行exec
        console.log ( resArr );
        resArr = reg.exec(str);
    };
​
    //示例3:如果正则有分组,则数组从1下标开始获取分组对应的字符
    var reg1 = /\d(\w)(\w)/;
    console.log ( reg1.exec ( str ) );//["1ab", "a", "b", index: 0, input: "1absjdg2cdjahsgd3ef", groups: undefined]

1.8-常用正则表达式总结

比较常用

  • 1.Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*.\w+([-.]\w+)*$

  • 2.手机号码:^(13[0-9]|14[57]|15[0-9]|17[067]|18[0-9])\d{8}$

  • 3.国内电话号码(0511-4405222、021-87888822):^0\d{2,3}[-]\d{7,8}$

  • 4.身份证号( 位、 位数字):^\d{* }|\d{* }$

  • 5.密码强度

    • 只有大小写字母:^([a-z].*[A-Z])|([A-Z].*[a-z])$
    • 大小写字母与数字:^([a-z].*[0-9])|([A-Z].*[0-9])|[0-9].*[a-zA-Z]$
    • 大小写字母+数字+下划线:^[A-Za-z0-9]+[_][A-Za-z0-9]*
  • 6.电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX)

    • ^((\d{3,4}-)|\d{3.4}-)?\d{7,8}$
  • 7.域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,* }(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,* })+/.?

  • 8.InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$