JS的正则表达式

151 阅读5分钟

认识正则

  • 正则表达式(规则表达式)
    • 我们自己来写规则,然后专门用来检测 字符串 是否符合规则
    • 创建正则
        1. var reg = /正则在这里边/
        var reg = /abc/
        console.log(reg)
        
        1. var reg = new RegExp('正则写在这里边')
        var reg2 = new RegExp('abcd')
        console.log(reg2)
        

正则的常用方法

  • 1.匹配
    • test 匹配字符串是否符合正则规则
      • true 符合规则
      • false 不符合
      var reg = /abc/ //匹配一段字符串中是否包含'abc'
      var str1 = 'a'
      var str2 = 'ab'
      var str3 = 'abc'
      var str4 = 'abcd'
      var str5 = 'a1b2c3'
      console.log(reg.test(str1)) //false
      console.log(reg.test(str2)) //false
      console.log(reg.test(str3)) //true
      console.log(reg.test(str4)) //true
      console.log(reg.test(str5)) //false
      
  • 2.捕获
    • 语法:正则.exec(字符串)
      • 1.字符串没有符合正则规则的内容
        • 捕获的结果为null
        var reg = /\d{3}/
        console.log(reg.exec('qwertyuiop')) //null
        
      • 2.正则没有小括号,没有标识符g
        • 捕获到的是一个数组,下标0是我们捕获到的值,但是不管捕获多少次,都是从下标[0]开始,第一个满足条件的
        var reg = /\d{3}/
        console.log(reg.exec('qwe123rty456uiop789')) //[0]:123
        console.log(reg.exec('qwe123rty456uiop789')) //[0]:123
        
      • 3.有小括号
        • 下标0是符合正则规则的字符串
        • 从下标1开始时,每个小括号单独捕获出来的内容
        var reg = /(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/
        var num = '411381200401311234'
        console.log(reg.exec(num))
        
      • 4.有标识符 g
        • g叫做全局标识符
        • 第二次捕获的时候,会从第一次捕获结束的位置开始进行捕获
        • 直到找不到内容,会返回一个null
        • 然后在下一次捕获的时候,会从字符串开始位置重新捕获
         var reg = /\d{3}/g
         var str = 'qwe123rty456uiop789'
         console.log(reg.exec(str)) //[0]:123
         console.log(reg.exec(str)) //[0]:456
         console.log(reg.exec(str)) //[0]:789
         console.log(reg.exec(str)) //null
         console.log(reg.exec(str)) //[0]:123
        

正则的元字符

  • 正则表达式的符号,由两种符号组成
    1. 元字符
    • 正则的规则符号
      • 普通文本--正则的规定符号
    1. 修饰符
    • 修饰整个正则表达式的符号
  • 普通元字符
      1. \d 表示一位 数字(0-9)
      var reg = /\d/  //匹配字符串中包含一位数字
      console.log(reg.test('abcd')) //false
      console.log(reg.test('abcd@#$%^&*')) //false
      console.log(reg.test('123456789'))  //true
      
      1. \D 表示一位非数字(除了0-9)
      var reg = /\D/
      console.log(reg.test('abcd')) //true
      console.log(reg.test('abcd@#$%^&*')) //true
      console.log(reg.test('123456789'))  //false
      
      1. \s 表示一位 空白内容(空格,缩进)
      var reg = /\s/
      console.log(reg.test('123456!@#$%^&*qwerty')) //false
      console.log(reg.test('123456 !@#$%^&* qwerty')) //true
      
      1. \S 表示一位 非空白内容
      var reg = /\S/
      console.log(reg.test('123456!@#$%^&*qwerty')) //true
      console.log(reg.test('123456 !@#$%^&* qwerty')) //true
      console.log(reg.test(' ')) //false
      
      1. \w 表示一位 数字(0-9)字母(a-z A-Z)下划线(_)
      var reg = /\w/ //匹配字符串中 包含一位 数字(0-9)字母(a-z A-Z)下划线(_)
      console.log(reg.test('abc')) //true
      console.log(reg.test('a1b2c3')) //true
      console.log(reg.test('a1b2_c3')) //true
      console.log(reg.test('!@#$%^&*'))//false
      
      1. \W 表示一位 非数字字母下划线的内容
      var reg = /\W/ //匹配字符串中 包含一位非数字字母下划线的内容
      console.log(reg.test('abc')) //false
      console.log(reg.test('abc123')) //false
      console.log(reg.test('abc123_')) //false
      console.log(reg.test('!@#$%^&*')) //true
      console.log(reg.test(' ')) //true
      
      1. . 表示一位 非换行内容
       var reg = /./
       console.log(reg.test('!@#$%^')) //true
       console.log(reg.test('asdf')) //true
       console.log(reg.test('123')) //true
       console.log(reg.test('\n')) //false  \n 在JS 中代表换行
      
      1. \ 表示 转义符
      var reg = /\d\.\d/ //  \. 表示一个小数点,没有任何特殊含义
      console.log(reg.test('abc')) //false
      console.log(reg.test('5.7')) //true
      console.log(reg.test('100')) /false
      

正则的边界元字符

    1. ^ 表示开头
    var reg = /^\d/ //表示字符串开头需要是一位数字
    console.log(reg.test('100abc')) //true
    console.log(reg.test('abc100')) //false
    
    1. $ 表示结尾
    var reg = /\d$/ //表示字符串结尾需要是一位数字
    console.log(reg.test('100abc')) //false
    console.log(reg.test('abc100')) //true
    
    1. 当开头与结尾共同使用时,表示字符串必颈是规则里的内容
    var reg = /abc/ //表示字符串中包含'abc'
    console.log(reg.test('abcd')) //true
    
    var reg = /^abc$/ //表示字符串必须是'abc'
    console.log(reg.test('abcd')) //false
    

正则的限定元字符

  • 限定了 前一个符号 出现多少次
    1. *表示0~正无穷次
var reg = /^\d*$/
console.log(reg.test('abc')) //false
console.log(reg.test('_999')) //false
console.log(reg.test('666')) //true
    1. +表示1~正无穷次
var reg = /^\d+$/
console.log(reg.test('abc')) //false
console.log(reg.test('_999')) //false
console.log(reg.test('666')) //true
console.log(reg.test(' ')) //false
console.log(reg.test('!')) //false
    1. ?表示0~1次
var reg = /^\d?$/
console.log(reg.test('6'))
console.log(reg.test('66'))
    1. {n}表示限定 n 次
var reg = /^\d{3}$/
console.log(reg.test('6')) //false
console.log(reg.test('66')) //false
console.log(reg.test('666')) //true
console.log(reg.test('6666')) //false
    1. {n,}表示限定 最少n 次
var reg = /^\d{3,}$/
console.log(reg.test('6')) //false
console.log(reg.test('66')) //false
console.log(reg.test('666')) //true
console.log(reg.test('6666')) //true
    1. {n,m}表示限定 最少n 次,最多m次
var reg = /^\d{3,4}$/
console.log(reg.test('6')) //false
console.log(reg.test('66')) //false
console.log(reg.test('666')) //true
console.log(reg.test('6666')) //true
console.log(reg.test('66666')) //false

正则的特殊元字符

    1. ()
    • 含义1:单独捕获()
    • 含义2:一个整体
    var reg = /^(abc){2}$/
    console.log(reg.test('abc')) //false
    console.log(reg.test('abcabc')) //true
    console.log(reg.test('abcqwe')) //false
    1. |
    • 含义:或 a|b
    • 表示左右两边满足一个就行,/a|b/ 表示满足a或者b哪个都可以
        var reg = /a|b/
        console.log(reg.test('a')) //true
        console.log(reg.test('b')) //true
        console.log(reg.test('c')) //false
    
    • 元字符或的分界线在哪里
      • 或的分界线为小括号 或者 正则的边界
        var reg = /^abc|def$/
        /**
         * 分析:
         *    /^abc|def$/
         *        ^abc 或者 def$
         * */ 
        console.log(reg.test('abc12345678')) //true
        console.log(reg.test('12345678def')) //true
        console.log(reg.test('1234abcdef5678')) //false
        
        var reg = /^ab(c|d)ef$/
        /**
         * 分析:
         *    ^ab c ef$
         *    ^ab d ef$
         * */ 
        console.log(reg.test('abcef')) //true
        console.log(reg.test('abdef')) //true
        console.log(reg.test('qwef')) //false
        console.log(reg.test('abqwe')) //false
    
    1. [] 包含 中括号内 其中一个即可
    • 在中括号中可以书写任意数量的符号,但是字符串只要满足其中一个即可
    var reg = /^[abcd]$/
    /**
     * 含义:
     *    字符串中,包含a b c d 任意一个即可
     * */
    console.log(reg.test('a')) //true
    console.log(reg.test('b')) //true
    console.log(reg.test('c')) //true
    console.log(reg.test('d')) //true
    console.log(reg.test('abcd')) //false
    1. [^] 非 不包含
    • 在中括号内可以书写任意数量的符号,只要字符串不是其中的某一个就行
    var reg = /^[^abcd]$/ //字符串中不是a b c d即可
    console.log(reg.test('a')) //false
    console.log(reg.test('c')) //false
    console.log(reg.test('w')) //true
  • 5.- 到 至
    • 通常和 [] [^] 连用
      • /[0-9]/ 正则代表的含义 数字0~9,等价于\d
      • /[^0-9]/ 正则代表的含义 非数字0~9,等价于\D
      • /[a-z]/ 表示字母a~z
      • /[0-9a-zA-Z]/ 等价于\w

正则的重复元字符

  • 符号:\数字
  • 含义: 表示重复第n个小括号的内容,并且要求和小括号的内容完全一致
    var reg = /^(abc|def)\1$/
    /**
     * \1 重复前面第一个小括号内容,小括号如果是'abc',那么\1的值也需要是'abc'
     * */ 
    console.log(reg.test('abcabc')) //true
    console.log(reg.test('defdef')) //true
    console.log(reg.test('abcdef')) //false
    console.log(reg.test('defabc')) //false
    /**
     * 要求 字符串是span 标签 或者 p 标签
     * */ 
    var reg = /<(span|p)><\/\1>/
    console.log(reg.test('<span></span>'))
    console.log(reg.test('<p></p>'))

正则的标识符

  • 书写在正则外面,用来描述整个正则表达式
    1. i
    • 表示忽略大小写
    1. g
    • 表示全局
    var reg = /^[abcd]$/i
    console.log(reg.test('a')) //true
    console.log(reg.test('A')) //true
    console.log(reg.test('w')) //false

案例要求:

  • 将字符串内所有满足正则规则的片段全部捕获出来,放到一个数组内
    var reg = /\d{3}/g
    var str = 'qwe123asd456zxc789'
    var arr = []
    var newStr = reg.exec(str)
    while(newStr !== null) {
      arr.push(newStr[0])
      newStr = reg.exec(str)
    }
    console.log(arr)
    /**
     * ['123', '456', '789']
     * */ 

正则的两大特性

  • 1.懒惰
    • 每次捕获 都是在 下标[0]的位置开始捕获
    • 解决: 在正则后添加全局标识符 g
  • 2.贪婪
    • 每次捕获内容的时候,尽可能的多去捕获内容
    • 解决: 使用非贪婪限定符 (再有的限定符后添加一个?)
    • 贪婪限定符
      •    *
        
      •    +
        
      •    {n,}
        
      •    {n,m}
        
    • 非贪婪限定符
      •    *?
        
      •    {n,}?
        
    var str = '<div class="box" id="id_box"><span></span></div>'

    // 贪婪捕获
    var reg1 = /<div.*>/
    console.log(reg1.exec(str)[0])

    // 非贪婪捕获
    var reg2 = /<div.*?>/
    console.log(reg2.exec(str)[0])

正则两种创建方式的区别

  • 1.书写标识符
    • 字面量的方式,直接在正则后书写标识符
    • 内置构造函数的方式,需要写在第二个参数中
    let reg1 = /abc/
    let reg2 = new RegExp('qwe', 'ig')
  • 2.书写元字符
    let reg1 = /\d\w\s\./
    console.log(reg1) // /\d\w\s\./

    // let reg2 = new RegExp('\d\w') // /dw/
    let reg2 = new RegExp('\\d\\w') // /\d\w/
    console.log(reg2) 
    
    /**
     * 在字符串中,如果书写了\ 那么相当于转义符,将后边的字符转换为 有意义的字符
     *    但是 转换完成之后, \就会自动消失, 那么正则拿到的就是一个具有特殊含义的字符d
     *    但是又因为 正则中 元字符必须是\ + d  结合在一起才是一个元字符,如果只有一个d 那么就是一个普通的字母,没有任何特殊含义
     * 
     * 解决方式:
     *    在原本的\前再添加一个 \
     *    第一个\ 将 第二个\ 转换为没有任何意义的普通文本,最终正则拿到的就是一个 没有特殊含义的\ + d
     *    然后按照正则的规则中,\+d就是一个元字符,代表的是数字0-9
     * */