JavaScript正则表达式

111 阅读2分钟

什么是正则表达式

正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。

正则的使用

  • 定义
let reg1 = /a/ // 字面量
let reg2 = new RegExp('a') // 构造函数
  • 区别
let str = 'a'
let reg1 = /a/
let reg2 = new RegExp(str) // 可以使用变量
console.log(reg1,'reg1')
console.log(reg2,'reg2')

image.png

正则的方法

  • test() 检测一个内容是否与正则匹配
  1. 如果匹配返回true
  2. 如果不匹配返回false
  • exec() 检测一个内容是否与正则匹配
  1. 如果匹配返回数组
  2. 如果不匹配返回null

元字符

[] 匹配中括号内(任意一个)字符

// 验证手机号
// 比如第二位固定 3,5,7,8
let reg = /^1[3578]\d{9}$/
console.log(reg.test(13600000000)) // true
console.log(reg.test(15600000000)) // true
console.log(reg.test(17600000000)) // true
console.log(reg.test(18600000000)) // true
console.log(reg.test(19600000000)) // false

[^] 除了括号内任意字符

[0-9] 匹配数字0-9范围

[a-z] [A-Z] [a-zA-Z] 匹配字母

\d 匹配数字

\D 匹配非数字

\w 匹配数字字母下划线 => [a-zA-Z0-9_]

\W 匹配非数字字母下划线

\s 匹配空格

let reg = /\s/
let str = ' '
console.log(reg.test(str)) // true

\S 匹配非空格

\b 边界

let reg = /\ba/
let str1 = 'ba'
console.log(reg.test(str1)) // false
let str2 = 'a'
console.log(reg.test(str2)) // true
let str3 = 'b a'
console.log(reg.test(str3)) // true

\B 匹配非边界

. 除了换行符以外的任意字符

转义(\)

// . 除了换行符以外的任意字符
let reg = /./
let str = 'a'
console.log(reg.test(str)) // true 

// 使用 \ 转义 
let reg = /\./ //此时这个 . 他只代表 . 
let str1 = 'a'
console.log(reg.test(str1)) // false 
let str2 = '.'
console.log(reg.test(str2)) // true 

选择符

| => 或

// www.xxx.com
// www.xxx.cn
// ...

let reg = /com|cn/
let str1 = 'com'
console.log(reg.test(str1)) // true

修饰符

i 不区分大小写

g 全文匹配

let str = '你好啊,你好呀'
// 当前正则没有加 g
let reg1 = /你/
console.log(str.replace(reg1,'*')) // *好啊,你好呀
// 加上g修饰符
let reg2 = /你/g
console.log(str.replace(reg2,'*')) // *好啊,*好呀

字符串方法可以配合正则使用

replace

match: 类似于exec,查找返回对应的值(值是数组) 没有找到返回null

// exec 和 match 区别
// 注意 这里加上了 g 
let reg = /a/g
let str = 'abcabc'
console.log(reg.exec(str)) // ['a', index: 0, input: 'abcabc', groups: undefined]
console.log(str.match(reg)) // ['a', 'a']

image.png

let inp = document.querySelector(".inp")

let ul = document.querySelector(".ul")

let reg = /大爷|草/g

inp.onkeydown = (e) => {
    let value = inp.value;
    if(reg.test(value)) {
        value = value.replace(reg,"*")
    }
    if (e.keyCode == 13) {
        let li = document.createElement("li")
        li.innerHTML = value
        ul.appendChild(li)
        inp.value = ""
    }
}

限定符

^ 开始

$ 结束

// 验证手机号:11 位手机号

// 以 1 开始

// 第二位 3,5,7,8

// 以数字结束

// 1. 以数字1开始
let reg = /^1/
console.log(reg.test(1)) // true

// 2. 第二位 3,5,7,8
let reg = /^1[3578]/
console.log(reg.test(17)) // true

// 3. 以数字结束
let reg = /^1[3578]\d\d\d\d\d\d\d\d\d$/
console.log(reg.test(17600000000)) // true

// 4.简写
let reg = /^1[3578]\d{9}$/
console.log(reg.test(17600000000)) // true

重复

{n} 重复n次

{n,} 重复最少n次,最多不限

{n,m} 重复最少n次,最多m次

( * ) 最少0次,最多不限

( + ) 最少一次,最多不限

( ? ) 最少0次,最多一次

let reg = /^a?$/
console.log(reg.test('')) // true
console.log(reg.test('a')) // true
console.log(reg.test('aa')) // false

贪婪模式

let reg = /\d{3,6}/
let str1 = '123456789'
let str2 = 'abc123456789'
console.log(str1.replace(reg, '*')) // *789
console.log(str2.replace(reg, '*')) // abc*789

非贪婪模式

let reg = /\d{3,6}?/
let str1 = '123456789'
let str2 = 'abc123456789'
console.log(str1.replace(reg, '*')) // *456789
console.log(str2.replace(reg, '*')) // abc*456789

分组

() 把部分内容组合在一起

let str = 'abcabcabc'

let reg1 = /abc{3}/
console.log(reg1.test(str1)) // fasle

let reg2 = /(abc){3}/
console.log(reg2.test(str)) // true

字符类 (得到 获取分组内的内容)

$1

$2

$3

...

let str = '2023-02-17'
let reg = /^(\d{4})-(\d{2})-(\d{2})$/
console.log(reg.test(str)) // true 必须要执行一次才能拿到
console.log(RegExp.$1) // 2023
console.log(RegExp.$2) // 02
console.log(RegExp.$3) // 17

前瞻 => if

image.png

正向前瞻 (?=) 匹配符合的

// 数字后面是字母的
let str = '1a2a3a'
let reg = /\d(?=[a-z])/g // (?=[a-z]) 只是一个条件
console.log(str.replace(reg,'-')) // -a-a-a

负向前瞻 (?!) 匹配不符合的

// 数字后面不是字母的
let str = '1a2a3'
let reg = /\d(?![a-z])/g // (?=[a-z]) 只是一个条件
console.log(str.replace(reg,'-')) // 1a2a-

小案例:必须有数字必须有字母,并且是3-6位

// 必须有数字
// 必须有字母
// (?=.*\d) 任意字符后必须要有数字
// (?=.*[a-z]) 任意字符后必须要有字母
let str1 = '1ab'
let str2 = 'a12'
let reg = /^(?=.*\d)(?=.*[a-z])[0-9a-z]{3,6}$/i
console.log(reg.test(str1)) // true
console.log(reg.test(str2)) // true

案例

  1. 验证手机号,用户名

  1. 手机号钝点17600000000 => 176 0000 0000
let phone = 17600000000
let reg = /(\d{3})(\d{4})(\d{4})/
reg.test(phone)
console.log(RegExp.$1) // 176
console.log(RegExp.$2) // 0000
console.log(RegExp.$3) // 0000
  1. 判断一个字符串中出现次数最多的字符,并且统计次数
let value = ''

let len = 0

let str = 'bbccaaaeeedseeeddfsf'

// 切个成数组,排序 ['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd', 'd', 'e', 'e', 'e', 'e', 'e', 'e', 'f', 'f', 's', 's']
let arr = str.split("").sort();

// 转成字符串 aaabbccdddeeeeeeffss
str = arr.join("")

// 正则匹配到了重复的内容 ['aaa', 'bb', 'cc', 'ddd', 'eeeeee', 'ff', 'ss']
let reg = /(\w)\1+/g;
let newArr = str.match(reg)

// 循环
newArr.forEach((item,index) => {
    if(len < item.length) {
        len = item.length
        value = item
    }
})
console.log(value) // eeeeee
console.log(len) // 6