前端学习正则表达式
Juns正则表达式
一直以来都避免接触正则 😠,因为感觉都是啥,看不懂,好难看,不想学 🥺。不过还是有必要了解学习一下的,至少要能看懂,知道在什么时候使用它,当然具体的表达式可以直接百度或者问 GPT,看得懂意思就好。
正则表达式是匹配模式
,要么匹配字符
,要么匹配位置
。
搞懂位置能干啥?
- 数字的千分位分割法
123456789 -> 123,456,789
- 手机号 3-4-4 分割
12345678901 -> 123-4567-8901
- 密码合法性校验
密码长度是 6-12 位,由数字、小写字符和大写字母组成,但必须至少包括 2 种字符
上面也都是很常见的需求,正则可以很方便的解决他们
什么是位置
位置可以理解为相邻字符之间的位置,可以类比为空字符串,在字符的首尾、间隙用空字符连接
'he' === '' + 'h' + '' + 'e' + ''
|
有哪些位置
正则中常用来表示位置的符号主要有:
^
、$
、\b
、\B
、?=p
、(?!p)
、(?<=p)
、(?<!p)
^
匹配行的开头
如果要在 hello 开头赛一个笑脸 😊,就可以这么写
let str = 'hello' console.log(str.replace(/^/, '😊'))
|
$
匹配行的结尾
同理在 hello 的末尾赛一个笑脸 😊
console.log('hello'.replace(/$/, '😊'))
|
\b
单词的边界
匹配一个单词边界,即字和空格之间的位置
比如想把xxx_1.mp4
变成❤️xxx_1❤️.❤️mp4❤️
,就可以这么写
let str = 'xxx_1.mp4' console.log(str.replace(/\b/, '❤️'))
console.log(str.replace(/\b/g, '❤️'))
|
\B
非单词的边界,就是和\b 相反
直接看例子吧:
let str = 'xxx_1.mp4' console.log(str.replace(/\B/, '❤️'))
console.log(str.replace(/\B/g, '❤️'))
|
(?=p)
p 为正向先行断言,表示 p 前面的位置
比如想把xxx_1.mp4
变成❤️xxx_1.mp4
,就可以这么写
let str = 'xxx_1.mp4' console.log(str.replace(/(?=xxx)/, '❤️'))
|
(?!p)
p 为负向先行断言,表示不在 p 前面的位置
let str = 'xxx_1.mp4' console.log(str.replace(/(?!xxx)/, '❤️'))
console.log(str.replace(/(?!xxx)/g, '❤️'))
|
(?<=p)
p 为正向后行断言,表示 p 后面的位置
let str = 'xxx_1.mp4' console.log(str.replace(/(?<=xxx)/, '❤️'))
|
(?<!p)
p 为负向后行断言,表示不在 p 后面的位置
let str = 'xxx_1.mp4' console.log(str.replace(/(?<!xxx)/, '❤️'))
console.log(str.replace(/(?<!xxx)/g, '❤️'))
|
尝试做题
数字的千分位分割法
将 123456789 转化为 123,456,789
从后往前,每 3 个数字前面加一个逗号,这很符合(?=p)
- 先吧最后一个逗号弄出来
let price = '123456789' let priceReg = /(?=\d{3}$)/ console.log(price.replace(priceReg, ','))
|
- 弄出所有的逗号
let price = '123456789' let priceReg = /(?=(\d{3})+$)/g
console.log(price.replace(priceReg, ','))
|
- 去掉第一个逗号
let price = '123456789' let priceReg = /(?!^)(?=(\d{3})+$)/g
console.log(price.replace(priceReg, ','))
|
手机号 3-4-4 分割
12345678901 -> 123-4567-8901
let phone = '12345678901' let phoneReg = /(?=(\d{4})+$)/g console.log(phone.replace(phoneReg, '-'))
|
手机号 3-4-4 分割拓展
要求这样的形式
123 => 123 1234 => 123-4 12345 => 123-45 123456 => 123-456 1234567 => 123-4567 12345678 => 123-4567-8 123456789 => 123-4567-89 12345678911 => 123-4567-8911
|
这个就是和从前往后
- 先弄第一个 -
const formatPhone = phone => String(phone).replace(/(?<=\d{3})\d+/, '-') console.log(formatPhone(123)) console.log(formatPhone(1234))
|
- 第二个
const formatPhone = phone => String(phone) .slice(0, 11) .replace(/(?<=\d{3})\d+/, str => `-${str}`) .replace(/(?<=[\d-]{8})\d{1,4}/, str => `-${str}`)
console.log(formatPhone(123)) console.log(formatPhone(1234)) console.log(formatPhone(12345)) console.log(formatPhone(123456)) console.log(formatPhone(1234567)) console.log(formatPhone(12345678)) console.log(formatPhone(123456789)) console.log(formatPhone(12345678911))
|
校验密码合法性
密码长度是 6-12 位,由数字、小写字符和大写字母组成,但必须至少包括 2 种字符
- 6-12 位
- 数字、小写、大写
- 至少 2 种
先写 12 俩条件
let reg = /^[a-za-Z\d]{6-12}$/
|
条件 3
let reg = /^(?![a-z]+$)(?![A-Z]+$)(?!\d+$)[a-zA-Z\d]{6,12}$/ console.log(reg.test('123456')) console.log(reg.test('aaaaaa')) console.log(reg.test('AAAAAAA')) console.log(reg.test('1a1a1a')) console.log(reg.test('1A1A1A')) console.log(reg.test('aAaAaA')) console.log(reg.test('1aA1aA1aA'))
|
字符串匹配
俩种模糊匹配
横向
通过+
、*
、?
、{m,n}
,可实现横向匹配
let reg = /ab{2,5}c/g let str = 'abc abbc abbbc abbbbc abbbbbc abbbbbbc' console.log(str.match(reg))
|
纵向
通过[]
,可实现纵向匹配
let reg = /a[123]b/g let str = 'a0b a1b a2b a3b a4b' console.log(str.match(reg))
|
字符组
虽然叫字符组,不过也有可能只有一个字符
范围表示法
[123456abcdefABCDEF] => [1-6a-fA-F]
|
排除字符组
使用^来排除
let reg = /[^abc]/g let str = 'a0b23' console.log(str.replace(reg, '❤️'))
|
常见简写
量词
量词 简写
1. {m,} 2. {m} 3. {m,n} 3. ? 4. + 5. *
|
贪婪匹配 惰性匹配
贪婪会尽可等多匹配符合模式的字符
let regex = /\d{2,5}/g let string = '123 1234 12345 123456' string.match(regex)
let regex2 = /\d{2,5}?/g string.match(regex)
|
多选分支
let regex = /good|nice/g let string = 'good idea, nice try.' string.match(regex)
|
题目
- 匹配 id
let regex1 = /id=".*?"/
let string = '<div id="container" class="main"></div>' console.log(string.match(regex1)[0])
let regex2 = /id="[^"]*"/ console.log(string.match(regex2)[0])
|
- 匹配 16 进制颜色值
let regex = /#([a-fA-F\d]{6}|[a-fA-F\d]{3})/g let string = '#ffbbad #Fc01DF #FFF #ffE'
console.log(string.match(regex))
|
- 匹配 24 小时制时间
let regex = /^([01]\d|2[0-3]):[0-5]\d$/
console.log(regex.test('23:59')) console.log(regex.test('02:07'))
let regex = /^(0?\d|1\d|2[0-3]):(0?|[1-5])\d/
console.log(regex.test('23:59')) console.log(regex.test('02:07')) console.log(regex.test('7:09'))
|
括号的作用
分组
让量词作用于一个整体
let reg = /(ab)+/g let string = 'ababa abbb ababab'
console.log(string.match(reg))
|
分支结构
let reg = /I love (JavaScript|Regular Expression)/
console.log(reg.test('I love JavaScript'))
console.log(reg.test('I love Regular Expression'))
|
总结
感觉还是不好理解,不过能看懂一些符号的含义了 ☹️
参考链接