JS的正则表达式

41 阅读7分钟

正则

  • 正则表达式, 又名 "规则表达式"
  • 由我们自己来书写 "规则", 专门用来检测 字符串 是否符合 "规则" 使用的
  • 我们使用一些特殊的字符或者符号定义一个 "规则公式", 然后用我们定义好的 "规则公式" 去检测字符串是不是合格

创建正则

  • var reg = /正则在这里边/
  • var reg = new RegExp('正则在这里面')

正则常用的方法

1.test 匹配字符串是否符合正则规则

  • 符合规则 true 不符合规则 false

2.捕获(暂时不讲)

       var reg = /abc/
       var str = 'a'
       var str1 = 'ab'
       var str2 = 'abc'
       var str3 = 'abcd'
       var str4 = 'ab1c3d'
       //判断字符串里面是否包含正则里面的内容
       console.log(reg.test(str));
       console.log(reg.test(str1));
       console.log(reg.test(str2));
       console.log(reg.test(str3));
       console.log(reg.test(str4));

正则的元字符

正则表达式的符号,由两种符号组成

  • 元字符:正则的规则符号:普通文本
  • 修饰符:修饰整个正则表达式的符号

一. 普通元字符

  • \d 表示一位数字(0-9)

  • \D 表示一位非数字(除了0-9)

  • \s 表示一位空白内容(空格 缩进)

  • \S 表示一位非空白内容

  • \w 表示一位数字(0-9) 字母(a-z,A-Z) 下划线(_)

  • \W 表示一位非数字 字母 下划线

  • .表示一位非换行内容

  • \ 表示转译符号, 把有意义的 符号 转换成没有意义的 字符, 把没有意义的 字符 转换成有意义的 符号

二.边界元字符

  • ^ 表示开头
  • $ 表示结尾
  • 开头与结尾共同使用的时候表示字符串必须是规则里面的内容

三.限定元字符

限定前一个符号出现多少次

  • *表示出现0-无穷次
  • + 重复至少 1 次, 也就是可以出现1~正无穷*次
  • ?重复 0 或者 1 次, 也就是可以出现0~1次
  • {n} 重复 n 次, 也就是必须出现n次
  • {n,} 至少出现 n 次, 也就是出现n ~ 正无穷次
  • {n, m} 至少出现 n 次至多出现 m 次, 也就是出现n~m次

四.特殊元字符

  • () 限定一组元素,含义1:单独捕获 2.一个整体

  • [] 字符集合, 表示写在 [] 里面的任意一个都行

  • [^]反字符集合, 表示写在 [^] 里面之外的任意一个都行

  • - 范围, 通常和[][^]连用.

     [0-9]正则代表数字0-9等价于\d.
     [^0-9]正则代表的含义非数字0-9等价于\D.
     [a-z]表示a-z.
     [0-9a-zaA-Z_]等价于\w.
     
    
  • | 或, a|b 表示字母 a 或者 b 都可以,或的分界线为小括号或者正则边界

五.重复元字符

  • \数字 表示重复第 n 个小括号的内容, 要求和第 n 个小括号的内容一摸一样
//一.普通元字符
    //1.\d 表示一位数字(0-9)
    var reg = /\d/
    console.log(reg.test('abc'));
    console.log(reg.test('1abc'));
    console.log(reg.test('abc@#$'));
    console.log(reg.test('1234'));

    //2.\D 表示一位非数字(除了0-9)
    var reg = /\D/
    console.log(reg.test('abc'));//true
    console.log(reg.test('1abc'));//true
    console.log(reg.test('abc@#$'));//true
    console.log(reg.test('1234'));//false

    //3.\s 表示一位空白内容(空格 缩进)
    var reg = /\s/
    console.log(reg.test('abc'));//false
    console.log(reg.test('1abc'));//false
    console.log(reg.test('abc@ #$'));//true
    console.log(reg.test(' 1234'));//true

    //4.\S 表示一位非空白内容
    var reg = /\S/
    console.log(reg.test('abc'));//true
    console.log(reg.test('1abc'));//true
    console.log(reg.test('abc@ #$'));//true
    console.log(reg.test(' 1234'));//true
    console.log(reg.test(' '));//false

    //5.\w 表示一位数字(0-9) 字母(a-z,A-Z) 下划线(_)
    var reg = /\w/
    console.log(reg.test('123')); //true 
    console.log(reg.test('a123')); //true
    console.log(reg.test('123a')); //true
    console.log(reg.test('ab')); //true
    console.log(reg.test('ab_')); //true
    console.log(reg.test('1ab_')); //true
    console.log(reg.test('#$@')); //false

    //6.\W 表示一位非 数字 字母 下划线
    var reg = /\W/
    console.log(reg.test('123')); //false
    console.log(reg.test('a123')); //false
    console.log(reg.test('123a')); //false
    console.log(reg.test('ab')); //false
    console.log(reg.test('ab_')); //false
    console.log(reg.test('1ab_')); //false
    console.log(reg.test('#$@')); //true
    console.log(reg.test('ab$#')); //true

    //7. . 表示一位非换行内容
    var reg = /./
    console.log(reg.test('ab'));//false
    console.log(reg.test('\n'));//true

    //8. \ 表示转译符号, 把有意义的 符号 转换成没有意义的 字符, 把没有意义的 字符 转换成有意义的 符号
    var reg = /\d\.\d/ //\.把非换行.转换为字符.
    console.log(reg.test('4.5'));//true
    console.log(reg.test('abc.d'));//false
    console.log(reg.test('100'));//false

    //二.边界元字符
    //1.^ 表示开头
    var reg = /^\d/
    console.log(reg.test('12asd'));//true
    console.log(reg.test('asd12'));//false
    //2.$ 表示结尾
    var reg = /\d$/
    console.log(reg.test('12asd'));//false
    console.log(reg.test('asd12'));//true
    //开头结尾一起使用情况
    var reg = /^abc$///表示字符串必须是abc
    console.log(reg.test('123abc'));//false
    console.log(reg.test('abc'));//true
    console.log(reg.test('abc123'));//false

    //三.限定元字符
    //1. * 表示前一个内容出现0-无穷次
    var reg = /^\d*$/
    console.log(reg.test('abc'));//false
    console.log(reg.test('abc12'));//false
    console.log(reg.test('1bc'));//false
    console.log(reg.test(''));//true
    console.log(reg.test('123'));//true

    //2.+ 重复至少 1 次, 也就是可以出现1~正无穷*次
    var reg = /^\d+$/
    console.log(reg.test('abc'));//false
    console.log(reg.test('abc12'));//false
    console.log(reg.test('1bc'));//false
    console.log(reg.test(''));//false
    console.log(reg.test('123'));//true

    //3.?`重复 0 或者 1 次, 也就是可以出现0~1次
    var reg = /^\d?$/
    console.log(reg.test('abc'));//false
    console.log(reg.test('abc12'));//false
    console.log(reg.test('1bc'));//false
    console.log(reg.test(''));//true
    console.log(reg.test('123'));//false
    console.log(reg.test('1'));//true

    //4.{n} 重复 n 次, 也就是必须出现n次
    var reg = /^\d{3}$/
    console.log(reg.test('abc'));//false
    console.log(reg.test('abc12'));//false
    console.log(reg.test('1bc'));//false
    console.log(reg.test(''));//false
    console.log(reg.test('123'));//true
    console.log(reg.test('1234333'));//false

    //5.{n,} 至少出现 n 次, 也就是出现n ~ 正无穷次
    var reg = /^\d{3,}$/
    console.log(reg.test('abc'));//false
    console.log(reg.test('abc12'));//false
    console.log(reg.test('1bc'));//false
    console.log(reg.test(''));//false
    console.log(reg.test('123'));//true
    console.log(reg.test('1234333'));//true
    console.log(reg.test('12'));//false

    //6.{n, m} 至少出现 n 次至多出现 m 次, 也就是出现n~m次
    var reg = /^\d{3,5}$/
    console.log(reg.test('abc'));//false
    console.log(reg.test('abc12'));//false
    console.log(reg.test('1bc'));//false
    console.log(reg.test(''));//false
    console.log(reg.test('123'));//true
    console.log(reg.test('1234333'));//false
    console.log(reg.test('1234'));//true

    //四.特殊元字符
    //1.() 限定一组元素,含义1:单独捕获 2.一个整体
    var reg = /(abc){2}/
    console.log(reg.test('abcabc'));//true
    console.log(reg.test('abc'));//false
    console.log(reg.test('abcqwe'));//false
    
    //2.[] 字符集合, 表示写在 [] 里面的任意一个都行
    var reg = /^[1234567]$/
    console.log(reg.test('1'));//true
    console.log(reg.test('0'));//false
    console.log(reg.test('9'));//false
    console.log(reg.test('6'));//true
    console.log(reg.test('123'));//false

    //3.[^] 反字符集合, 表示写在 [^] 里面之外的任意一个都行
    var reg = /[^1234567]/
    console.log(reg.test('1'));//false
    console.log(reg.test('0'));//true
    console.log(reg.test('9'));//true
    console.log(reg.test('6'));//false
    console.log(reg.test('123'));//false

    //4.- 范围, 比如 a-z 表示从字母 a 到字母 z 都可以,通常和[][^]连用
    var reg = /^[0-9]$/
    console.log(reg.test('1'));//true
    console.log(reg.test('10'));//false
    var reg = /[0-9]/
    console.log(reg.test('1'));//true
    console.log(reg.test('10'));//true

    // 5.| 或, a|b 表示字母 a 或者 b 都可以.或的分界线为小括号或者正则边界
    var reg = /a|b/
    console.log(reg.test('a'));//true
    console.log(reg.test('b'));//true
    console.log(reg.test('ab'));//true
    console.log(reg.test('abc'));//true
    console.log(reg.test('c'));//false
    var reg = /^ab|cd$/
    //分析ab或者cd
    console.log(reg.test('ab'));//true
    console.log(reg.test('ac'));//false
    console.log(reg.test('cd'));//true
    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('abced'));//false
    
    var reg = /^(abc|def)$/
    console.log(reg.test('abc'));//true
    console.log(reg.test('def'));//true
    console.log(reg.test('abcdef'));//false

    //五.重复元字符
    //\数字 表示重复第 n 个小括号的内容, 要求和第 n 个小括号的内容一摸一样
    //小案例:要求字符串是span 标签或者p标签
    var reg = /^<(span|p)><\/\1>$/
    console.log(reg.test('<span></span>'));//true
    console.log(reg.test('<p></p>'));//true
    console.log(reg.test('<div></div>'));//false

正则的标识符

书写在正则的外面,用来描述整个正则表达式

  • i 表示忽略大小写
  • g 表示全局匹配 */
  var reg = /^[abcde]$/i
  console.log(reg.test('a'));//true
  console.log(reg.test('A'));//true
  console.log(reg.test('B'));//true
  console.log(reg.test('Y'));//false
  console.log(reg.test('ac'));//false
  

正则的捕获

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

  • 字符串没有符合正则规则的内容,捕获的结果为null *正则没有小括号没有标识符g

    捕获到的是一个数组,下标0是我们捕获到的值,但是不管捕获多少次,都是从下标[0]开始的,第一个满足条件

  • 有小括号 下标0是符合正则规则的字符串

    从下标1开始 是每个小括号单独捕获出来的内容

  • 有标识符g(全局标识符)

    第二次捕获的时候会从第一次捕获结束的位置开始捕获*/

// 1.字符串没有符合正则规则的内容,捕获的结果为null
    var reg = /\d{3}/
    console.log(reg.exec('der'));//null
    console.log(reg.exec('123'));//['123', index: 0, input: '123', groups: undefined]

//2.正则没有小括号没有标识符g.捕获到的是一个数组,下标0是我们捕获到的值,但是不管捕获多少次,都是从下标[0]开始的,第一个满足条件
    var reg = /\d{3}/
    console.log(reg.exec('qwe'));//null
    console.log(reg.exec('qwe123rty456uio789'));//[0]:123['123', index: 3, input: 'qwe123rty456uio789', groups: undefined]

// 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 = '130123199901011234'
    console.log(reg.exec(num)); //['130123199901011234', '13', '01', '23', '19', '99', '01', '01', '12', '34', index: 0, input: '130123199901011234', groups: undefined]

//4.有标识符g(全局标识符):第二次捕获的时候会从第一次捕获结束的位置开始捕获
    var reg = /\d{3}/g
    var str = 'qwe123rty456uio789'
    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

正则的两大特性

  • 懒惰 每次捕获都是在[0]的位置开始捕获

  • 解决在正则后添加全局标识符g

  • 贪婪:每次捕获内容的时候,尽可能的夺取捕获内容

  • 解决:使用非贪婪限定符(在原有的限定符后添加一个?)

  • 贪婪限定符 * + ? {n,} {n,m}

  • 非贪婪限定符 *? +? ?? {n,}? {n,m}?

字符串的方法

字符串中有一些方法是可以和正则一起使用

search: 查找字符串中是否有满足条件的内容

  • 语法: 字符串.search(正则)
  • 返回值: 有的话返回开始索引, 没有返回 -1
var reg = /\d{3}/
var str1 = 'hello123'
var str2 = 'hello'
console.log(str1.search(reg))   // 5
console.log(str2.search(reg))   // -1

match: 找到字符串中符合正则条件的内容返回

  • 语法: 字符串.match(正则)
  • 返回值:
    • 没有标识符 g 的时候, 是和 exec 方法一样
    • 有标识符 g 的时候, 是返回一个数组, 里面是匹配到的每一项, 没有匹配到内容是返回的是 null
var reg = /\d{3}/
var str1 = 'hello123world456'
var str2 = 'hello world'
console.log(str1.match(reg))
/*
['123', index: 5, input: 'hello123world456', groups: undefined]
    0: "123"
    groups: undefined
    index: 5
    input: "hello123world456"
    length: 1
*/
console.log(str2.match(reg))    // -1
var reg = /\d{3}/g
var str1 = 'hello123world456'
var str2 = 'hello world'
console.log(str1.match(reg))    // ['123', '456']
console.log(str2.match(reg))    // null

replace: 是将字符串中满足正则条件的字符串替换掉

  • 语法: 字符串.replace(正则, 要替换的字符串)
  • 返回值: 替换后的字符串
var reg = /\d{3}/
var str1 = 'hello123world456'
var str2 = 'hello world'
console.log(str1.replace(reg, '哈哈哈哈'))    // hello哈哈哈哈world456
console.log(str2.replace(reg, '哈哈哈哈'))    // hello world
var reg = /\d{3}/g
var str1 = 'hello123world456'
var str2 = 'hello world'
console.log(str1.replace(reg, '哈哈哈哈'))    // hello哈哈哈哈world哈哈哈哈
console.log(str2.replace(reg, '哈哈哈哈'))    // hello world

正则两种创建方式的区别

  • 书写标识符:字面量的方式, 直接在正则后书写标识符.内置构造函数的方式, 需要写在第二个参数中
  • 需要写在第一个参数中,并且要给元字符加\转义符
        // 1. 书写标识符
        // let reg1 = /abc/i
        // let reg2 = new RegExp('qwe', 'ig')

        // 2. 书写元字符
        let reg1 = /\d\w\s.\./
        console.log(reg1)

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