正则/规则表达式篇

35 阅读5分钟

正则/规则 表达式

书写规则,专门用来检测某一段字符串是否符合规则

一、创建正则

  • 1.字面量方式: const reg = /正则符号/
  • 2.内置构造函数 const reg = new RegExp('正则符号')

二、正则的常用方法

  • 1.匹配:
    • 语法:正则.test(字符串)
    • 用于匹配某一个字符串是否符合规则
    • true 符合规则;false 不符合规则
    const reg = /abc/   // 正则的含义: 字符串中需要包含 'abc'

    const str1 = 'qwe123'
    const str2 = 'QF999'
    const str3 = '!@#abc$%^'
    const str4 = '!a@b#c$%^'
    
    console.log(reg.test(str1)) // fals
    console.log(reg.test(str2)) // false
    console.log(reg.test(str3)) // true
    console.log(reg.test(str4)) // false
  • 2.捕获

三、正则的元字符

有普通文本,也有正则规定的符号

1.普通元字符:

  • \d:表示一位数字(0-9)
    console.log(/\d/.test('15670'))    // true
    console.log(/\d/.test('whwewfn'))  // false
    console.log(/\d/.test('%^&*(^)'))  // false
  • \D:表示包含一位非数字(除0-9之外的)
    console.log(/\D/.test('!@#$%&'))   // true
    console.log(/\D/.test('15670'))    // false
    console.log(/\D/.test('qsqueuy'))  // true
  • \s:表示一位空白内容(空格,缩进)
    console.log(/\s/.test(' '))      // true
    console.log(/\s/.test('deg123')) // false
  • \S:表示包含一位非空白内容(除空格、缩进外)
    console.log((/\S/.test(' ')))    // false
    console.log(/\S/.test('15670'))  // true
  • \w:表示一位字母/数字/下划线
    console.log(/\w/.test('15670'))    // true
    console.log(/\w/.test('qwerty'))   //true
    console.log(/\w/.test('123_qwe'))  //true
    console.log(/\w/.test('!@#$%^'))   // false
  • \W:表示一位非字母/数字/下划线
    console.log(/\W/.test('15670'))    // false
    console.log(/\W/.test('qwerty'))   // false
    console.log(/\W/.test('123_qwe'))  // false
    console.log(/\W/.test('!@#$%^'))   // true
  • . :表示一位非换行内容
    console.log(/./.test(' '))   // true
  • \ :表示转义,可以将一个没有特殊含义的字符,转换为可能具有特殊含义,也可以将一个具有特殊含义的字符,转换为一个不具备特殊含义的字符

2.边界元字符

  • ^:表示开头
  • $:表示结尾
  • ^和$:组合到一起,是限制字符串只能是这个规则要求的
    // 字符串中需要包含一个数字(0-9), 数字在字符串的位置不受限制
    const reg1 = /\d/   
    // 字符串的开头必须是一个数字(0-9)
    const reg2 = /^\d/      
    // 字符串的末尾必须是一个数字(0-9)
    const reg3 = /\d$/      
     // 字符串只能是一个数字(0-9)
    const reg4 = /^\d$/    

    console.log(reg4.test('qwerty'))    // false
    console.log(reg4.test('1qwerty'))   // false
    console.log(reg4.test('qwe1rty'))   // false
    console.log(reg4.test('qwerty1'))   // false
    console.log(reg4.test('1'))   // true
    console.log(reg4.test('10'))   // false  数组范围是0-9,10表示的是字符串1和0

3.限定元字符

限定前一个符号出现的次数

  • *:表示0~正无穷次
    // 字符串只能由数字组成, 数字出现 0~正无穷次
    const reg = /^\d*$/ 
    console.log(reg.test('qwerty'))     // false
    console.log(reg.test(''))           // true
    console.log(reg.test('qf01'))       // false
    console.log(reg.test('1234567890')) // true
  • +:表示1~正无穷次
    // 字符串只能由数字组成, 数字出现 1~正无穷次
    const reg = /^\d+$/ 
    console.log(reg.test('qwerty'))   // false
    console.log(reg.test(''))         // false
    console.log(reg.test('qf001'))    // false
  • ?:表示0~1次
    // 字符串只能由数字组成, 数字出现 0~1
    const reg = /^\d?$/ 
    console.log(reg.test(''))       // true
    console.log(reg.test('9'))      // true
    console.log(reg.test('98888'))  // false
  • {}:表示限定n次,n表示一个数字
    // 字符串只能由数字组成, 数字必须出现 3 次
    const reg1 = /^\d{3}$/   
    console.log(reg1.test('1'))      // false
    console.log(reg1.test('12'))     // false
    console.log(reg1.test('123'))    // true
    console.log(reg1.test('1234'))   // false
  • {n,}:表示最少n次
    // 字符串只能由数字组成, 数字 最少出现 3 次
    const reg2 = /^\d{3,}$/   
    console.log(reg2.test('1'))      // false
    console.log(reg2.test('12'))     // false
    console.log(reg2.test('123'))    // true
    console.log(reg2.test('1234'))   // true
  • {n,m}:表示最少n次,最多m次
    // 字符串只能由数字组成, 数字 最少出现 3 次, 最多出现 5 次
    const reg2 = /^\d{3,5}$/   
    console.log(reg2.test('1'))         // false
    console.log(reg2.test('12'))        // false
    console.log(reg2.test('123'))       // true
    console.log(reg2.test('1234'))      // true
    console.log(reg2.test('12345'))     // true
    console.log(reg2.test('123456'))    // false

4.特殊元字符

  • ( ):表示将包含的内容当成一个整体
    // 表明当前字符串必须是 'abc'
    const reg1 = /^abc$/ 
    // 表明当前字符串必须是 'abcc'
    const reg2 = /^abc{2}$/  
    console.log(reg2.test('abc'))     // false
    console.log(reg2.test('abcc'))    // false
    console.log(reg2.test('abccc'))   // true
    console.log(reg2.test('abcabc'))  // false
        
    // 表明当前字符串必须是 abcabc
    const reg3 = /^(abc){2}$/   
    console.log(reg3.test('abc'))     //false
    console.log(reg3.test('abcc'))    //false
    console.log(reg3.test('abccc'))   //false
    console.log(reg3.test('abcabc'))  //true
  • |:表示左右两边满足其中一个就行 - 注意:| 有没有被()包裹,包裹:将小括号分成两个条件;没有包裹:将整个正则分成两个
    /**
      *  或 将当前正则分为两个
      *      满足左或者右就行
      *      左: /^abc/
      *      右: /def$/
     */
    const reg = /^abc|def$/
    console.log(reg.test('abc'))       // true
    console.log(reg.test('def'))       // true
    console.log(reg.test('abcdef'))    // true
    console.log(reg.test('qabc'))      // false
    console.log(reg.test('defq'))      // false
    console.log(reg.test('_abcdef_'))  // false
    /**
      *  如果或被 小括号 包含, 那么就不会将 正则分为两个了 
      *      当前正则的规则如下:
      *              1. a开头
      *              2. 后边跟上一个小写字母 b
      *              3. 小写 c 或者 小写 d 都可以
      *              4. 小写 e
      *              5. 以 f 结尾
     */
    const reg = /^ab(c|d)ef$/
    console.log(reg.test('abcef'))    // true
    console.log(reg.test('abdef'))    // true
    console.log(reg.test('abcdef'))   // false
  • [ ]:表示包含,例如[abcd],当前规则表明有一个字符,是abcd其中的一个就行
    // const reg = /^abcd$/     // 字符串只能是 abcd
    const reg = /^[abcd]$/      // 字符串是 abcd 其中的一个就行

    console.log(reg.test('a'))      // false   true
    console.log(reg.test('b'))      // false   true
    console.log(reg.test('c'))      // false   true
    console.log(reg.test('d'))      // false   true
    console.log(reg.test('abcd'))   // true  false
  • [^]:表示不包含,例如[^abcd],当前规则表明有一个字符,不是abcd其中的一个
    // 字符串是 abcd 其中的一个就行
    const reg = /^[abcd]$/    
    
    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('1'))  // false
    console.log(reg.test('@'))  // false
    console.log(reg.test('A'))  // false
  • -:一般需要和[ ]连用,例如[0-9],表明一个数字在0~9即可
    const reg = /^[0-9]$/
    console.log(reg.test('5'))     // true
    console.log(reg.test('10'))    //false
    console.log(reg.test('@'))     //false
    console.log(reg.test('w'))     //false
    console.log(reg.test('d'))     //false
    console.log(reg.test('D'))     //false

5.元字符的特别之处

    let reg1 = /^abc|def$/
    /*
     * 现在的正则其实是两个, 满足其中一个即可
     *     /^abc/ 如果一个字符串是 abc 开头即可
     *     /def$/ 如果一个字符串是 def 结尾即可
    */
    console.log(reg1.test('abc123'))   // true
    console.log(reg1.test('abc'))      // true
    console.log(reg1.test('def'))      // true
    console.log(reg1.test('123def'))   // true
    console.log(reg1.test('123'))      // false
    console.log('==========')

    let reg2 = /^(abc|def)$/
    // 当前正则可以理解为: /^abc$/  /^def$/
    console.log(reg2.test('abc'))     // true
    console.log(reg2.test('def'))     // true
    console.log(reg2.test('abcd'))    // false
    console.log('==========')

    const reg3  = /^ab(c|d)ef$/
    // 所以当前正则要求的是: /^abcef$/ /^abdef$/
    console.log(reg3.test('abcef'))     // true
    console.log(reg3.test('abdef'))     // true
    console.log(reg3.test('abcd'))      // false
    console.log('==========')

6.重复元字符

  • 语法:\1 \2 \3 \4 .... \n
    • 表明重复当前正则的 第 n 个 小括号中的内容
    // let reg = /<div></div>/    // 报错:正则的结束标签只有一个

    let reg1 = /<div><\/div>/
    console.log(reg1.test('<div></div>'))  // 只能判断div,不能判断p标签
    console.log('=========')

    let reg2 = /^<(div|p)><\/(div|p)>$/
    console.log(reg2.test('<div></div>'))    // true
    console.log(reg2.test('<p></p>'))        // true
    console.log(reg2.test('<div></p>'))      // true
    console.log(reg2.test('<p></div>'))      // true
    // 匹配结果不严谨,出现了<div></p>和<p></div>
    console.log('=========')

    // 需要重复元字符规范
    let reg3 = /^<(div|p)><\/\1>$/
    console.log(reg2.test('<div></div>'))    // true
    console.log(reg2.test('<p></p>'))        // true
    console.log(reg3.test('<div></p>'))      // false
    console.log(reg3.test('<p></div>'))      // false
    
    
    /**
      * 当前正则 中的 \1    是一个重复元字符, 重复的内容是当前正则 第一个小括号匹配的内容
      * 如果 第一个 小括号中的内容是 div,那么 \1 的值也是 div
      * 如果 第一个 小括号中的内容是 p,那么 \1 的值也是 p
      */
      
    const reg = /^<(div|p)><\/\1>$/
    /**
      * 当前正则 中的 \1 是一个重复元字符, 重复的内容是当前正则 第一个小括号匹配的内容
      * 如果 第一个 小括号中的内容是 div,那么 \1 的值也是 div
      * 如果 第一个 小括号中的内容是 p,那么 \1 的值也是 p
      */
    const reg = /^<(div|p)><\/\1>$/
    console.log(reg.test('<div></p>'))  // false
    console.log(reg.test('<p></div>'))  // false

7.标识符/修饰符

用于修饰整个正则的,所以需要写在正则的末尾

  • 1.i:表示忽略大小写
  • 2.g:表示 全局
    // 需求: 通过 下边的正则, 去捕获到 字符串中符合要求的部分, 并存放到某一个数组中
    const reg = /\d{3}/g
    let arr = []
    const str = 'qwe123rty456uio789'
    
    let res = reg.exec(str)
    while(res !== null) {
        arr.push(res[0])

        res = reg.exec(str)
    }
    console.log(arr)

四、两种创建正则的区别

  • 构造正则的方法:
      1. 字面量
      1. 内置构造函数
    let reg1 = /\d\w\s/
    console.log(reg1)    // /\d\w\s/

    const reg2 = new RegExp('\d\w\s')
    console.log(reg2)    // /dws/
    /**
      * 因为 \ 是一个转义字符,能够将有意义的字符转换为没有意义的,将没有意义的转换为没有意义的 
      * \d: \ 将字母d转换成了具有特殊含义的字符,但d本身没有任何特殊含义,所以内置构造函数的方法互殴的就是dws
    */ 

    //  解决方法
    const reg3 = new RegExp('\\d\\w\\s')
    console.log(reg3)    // /\d\w\s/

五、字符串中能使用正则的方法

  • 创建一个字符串
    const str = 'abc123def456ghi789'

- 1.replace()

- 字符串.replace('要找的字符串', '替换的字符串')
- 字符串.replace(正则, '替换的字符串')
    console.log(str.replace(/\d{3}/g, '000'))  // abc000def000ghi000

- 2.search()

- 字符串.search('字符串片段')
- 字符串.search(正则)
    console.log(str.search('1'))       // 3
    console.log(str.search(/\d{1}/))   // 3

- 3.match()

- 字符串.match('字符串片段')
- 字符串.match(正则)
    console.log(str.match('123'))    // ['123', index: 3, input: 'abc123def456ghi789', groups: undefined]
    console.log(str.match(/\d{3}/g))  // ['123', '456', '789']

六、正则的两大特性

    /**
      *  正则的两大特性
      *      1. 贪婪
      *         在捕获的时候, 尽可能的多去拿一些内容
      *         贪婪限定符, 如果在正则使用, 默认开启 贪婪模式
      *           *
      *           +
      *           ?
      *           {n,}
      *           {n,m}
      *         如果需要开启非贪婪模式, 直接在每一个贪婪限定符后添加一个 ?
      *            *?
      *            +?
      *            ??
      *            {n,}?
      *            {n,m}?
      * 
      *      2. 懒惰
      *         在正则中我们每一次捕获都是处于懒惰模式, 那么也就是说, 每一次都会从 [0] 开始捕获
      *         如果想要开启非懒惰模式, 只需要在 正则的最后添加一个修饰符 g
    */
    const str = '<div class="box" id="qf001"><p>你好, <span>JS</span></p></div>'

    const reg = /<div.*>/
    console.log(reg.exec(str)[0])  // '<div class="box" id="qf001"><p>你好, <span>JS</span></p></div>'
    
    const reg_1 = /<div.*?>/
    console.log(reg_1.exec(str)[0]) // <div class="box" id="qf001">