文章目录
1、创建正则表达式的方式
1.1、字面量形式
/^\d$/
- 测试:
/^\d$/.test('1') // true
const v = 'a'
eval(`/^${v}$/`).test('a') // true
1.2、对象
const reg = new RegExp('^\\d$', 'g') // 正则表达式语句, 模式修饰符
reg.test('99') // false
2、正则方法
2.1、exec()
用于检索字符串中的正则表达式的匹配结果。 返回一个存放第一次成功匹配结果的数组。如果未找到匹配,则返回 null
/./.exec('abcd') // ['a', index: 0, input: 'abcd', groups: undefined]
/./.exec('') // null
2.2、test()
用于检测一个字符串是否匹配某个模式,返回 boolean
/^\d$/.test('1') // true
/^\d$/.test('a') // false
2.3、可以用于正则的string方法
2.3.1、match()
将字符串中匹配的内容捕获出来,若加上量词g
则一次性捕获所有匹配的内容放到数组里返回,若不加则与exec()
的返回值一样
'\nabcd\n123'.match(/./) // ['a', index: 1, input: 'abcd', groups: undefined]
'\nabcd\n123'.match(/./g) // ['a', 'b', 'c', 'd', '1', '2', '3']
2.3.2、replace()
用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串
'\nabcd\n123'.replace(/\d/, '+') // '\nabcd\n+23'
'\nabcd\n123'.replace(/\d/g, '+') // '\nabcd\n+++'
// 小例子:替换座机号格式
const tels = '(010)9999999 (020)88888888'
console.log(tels.replace(/\((\d{3,4})\)(\d{6,7})/g, '$1-$2')) // 010-9999999 020-88888888
// 小例子:原子组在替换中的小技巧:把有数字的连续区间替换成一个-,@替换成&
const exc = 'abc.01+2def8g@hi99+'
console.log(exc.replace(/(\d+|@)/g, (item, ...args)=>{ // 第一个参数是匹配到的内容,后面就是正则表达式里所有的原子组
args[0] = item === '@' ? '&' : '-'
return args[0]
})) // abc.-+-def-g&hi-+
补充:$
在正则替换中的使用
- `$``:表示匹配内容前面的内容
$&
:表示匹配的内容$'
:表示匹配内容后面的内容
// 把文字左右两侧的内容展示双份
const word = '-=文字+-'
console.log(word.replace(/文字/, "$`$`$&$'$'")) // -=-=-=文字+-+-+-
2.3.3、search()
返回值是相匹配的子串的起始位置。 方法不执行全局匹配,它将忽略标志 g
'\nabcd\n123'.search(/./) // 1
'\nabcd\n123'.search(/./g) // 1 忽略g,写了也无效
2.3.4、split()
字符串的分割 ,返回一个数组。正则可以匹配它的分割方式
'\nabcd\n123'.split(/./) // (8) ['\n', '', '', '', '\n', '', '', '']
2.3.5、matchAll()
用于完成全局匹配
// 例子:取出标签里的所有内容
const htmlText = `
<h1>AAAAA</h1>
<h2>BBBBB</h2>
<h3>CCCCC</h3>
`
const ht = htmlText.matchAll(/<(h[1-6])>([\s\S]+?)<\/\1>/gi)
let all = []
for(const item of ht){
all.push(item[2])
}
console.log(all) // (3) ['AAAAA', 'BBBBB', 'CCCCC']
3、边界量词
^
:开始$
:结束
// 例子:校验以数字开始以字母s结尾的长度为2的字符串
/^\ds$/.test('1') // false
4、模式修饰符
i
:不区分大小写g
:全局匹配m
:多行匹配u
:\p
语法使用y
:连续匹配,与g
的区别就是遇到不匹配的直接停止匹配s
:。。。
模式修饰符可以一起使用,前后顺序无所谓
/aBc/igm
<==>/aBc/mgi
5、原子表[]
与原子组()
5.1、原子表[]
不是整个匹配,而是按照单一字符匹配
- 区间匹配(只能是升序)
[a-e]
表示匹配abcde[0-5]
表示匹配012345
- 排除匹配
^
[^abc]
表示排除abc;既不能是a也不能是b和c
- 注意:原子表内字符不会被解析
5.2、原子组()
-
原子组与原子表相通的关系:
(a|b|c|d)
<==>[abcd]
-
选择匹配
|
-
// 例子:匹配字符串 abc 或者 bcd /(abc|bcd)/.test('mabce') // true
-
-
分配原子组达到统一格式的目的(匹配的下标是从1开始
\1\2\3\...
)-
// 例子:日期格式校验 2022-11-18 2022/11/18 /^\d{4}[-\/]\d{2}[-\/]\d{2}$/ // 这样导致 2022/ 11-18 这种格式也会匹配成功,这里就需要用到原子组 // 原子组改进版日期格式校验 /^\d{4}([-\/])\d{2}\1\d{2}$/
-
-
不记录组
(?:x)
-
原子组取别名
(?<别名>x)
;获取用$<别名>
-
console.log('<h1>555</h1>'.replace(/<(h[1-6])>(.*?)<\/\1>/, '<h4>$2</h4>')) // <h4>555</h4> console.log('<h1>555</h1>'.replace(/<(h[1-6])>(?<context>.*?)<\/\1>/, '<h4>$<context></h4>')) // <h4>555</h4>
-
例子1:邮箱校验规则
/*
邮箱校验规则:
1、@之前必须有内容且只能是字母(大小写)、数字、下划线(_)、减号(-)、点(.)
2、@和最后一个点(.)之间必须有内容且只能是字母(大小写)、数字、点(.)、减号(-),且两个点不能挨着
3、最后一个点(.)之后必须有内容且内容只能是字母(大小写)、数字且长度为大于等于2个字节,小于等于6个字节
*/
/^[\w-\.]+@([a-zA-Z\d-]+\.)+[a-zA-Z\d]{2,6}$/
例子2:引用替换
通过
$i
引用对应下标的原子组
const hd = `
<h1>hahaha</h1>
<span>哈哈哈</span>
<h2>~~~</h2>
`
const reg = /<(h[1-6])>([\s\S]+)<\/\1>/gi
console.log(hd.replace(reg, `<p>$2</p>`))
/*
<p>hahaha</p>
<span>哈哈哈</span>
<p>~~~</p>
*/
例子3:批量使用正则
// 验证密码包含5-10位数字和字母混合且必须包含大写字母
const res = [/^[a-z\d]{5,10}$/i, /[A-Z]/, /\d/].every(r=>r.test('这是你的神奇小密码'))
6、元字符
元字符 | 描述 |
---|---|
. | 查找任意单个字符(除了换行和行结束符 ) |
\w | 查找单词字符(字母、数字、下划线 ) |
\W | 查找非单词字符 |
\d | 查找数字 |
\D | 查找非数字字符 |
\s | 查找空白字符、空格、制表符、换行符 |
\S | 查找非空白字符 |
\b | 匹配单词边界(词在[] 中无效) |
\B | 匹配非单词边界 |
\0 | 查找 null 字符 |
\n | 查找换行符 |
\f | 查找换页符 |
\r | 查找回车符 |
\t | 查找制表符 |
\v | 查找垂直制表符 |
\xxx | 查找以八进制数 xxxx 规定的字符 |
\xdd | 查找以十六进制数 dd 规定的字符 |
\uxxxx | 查找以十六进制 xxxx规定的 Unicode 字符 |
7、量词重复匹配
量词 | 描述 |
---|---|
n+ | 匹配任何包含至少一个 n 的字符串 |
n* | 匹配任何包含零个或多个 n 的字符串 |
n? | 匹配任何包含零个或一个 n 的字符串 |
n{x} | 匹配包含 x 个 n 的序列的字符串 |
n{x,y} | 匹配包含最少 x 个、最多 y 个 n 的序列的字符串 |
n{x,} | 匹配包含至少 x 个 n 的序列的字符串 |
●禁止贪婪
重复匹配默认是贪婪匹配,如果要禁止贪婪可在其后面添加?
// 贪婪
/\d*/.exec('123abc') // ['123', index: 0, input: '123abc', groups: undefined]
// 禁止贪婪
/\d*?/.exec('123abc') // ['', index: 0, input: '123abc', groups: undefined]
8、断言匹配
注意!!!断言不是原子组,只是匹配条件!!!
8.1、(?=xxx)
匹配后面是xxx的项
// 把后面是英文的数字区间替换成-
'123abcd0123Afgh3456ijMlm123'.replace(/\d+(?=[a-z])/gi, '-') // '-abcd-Afgh-ijMlm123'
8.2、(?<=xxx)
匹配前面是xxx的项
// 把前面是英文的数字区间替换成-
'123abcd0123Afgh3456ijMlm123'.replace(/(?<=[a-z]+)\d+/gi, '-') // '123abcd-Afgh-ijMlm-'
8.3、(?!xxx)
匹配后面不是xxx的项
// 把后面不是英文且处在结尾的数字区间替换成-
'123abcd0123Afgh3456ijMlm123'.replace(/\d+(?![a-z])$/gi, '-') // '123abcd0123Afgh3456ijMlm-'
8.4、(?<!xxx)
匹配前面不是xxx的项
// 把前面不是英文且处在开头的数字区间替换成-
'123abcd0123Afgh3456ijMlm123'.replace(/^(?<![a-z])\d+/gi, '-') // '-abcd0123Afgh3456ijMlm123'
9、汉字与字符属性
表示汉字的正则:[\u4e00-\u9fa5]
表示至少一个汉字的正则表达式:^[\u4e00-\u9fa5]
只含有汉字、数字、字母、下划线,下划线位置不限:^[a-zA-Z0-9_\u4e00-\u9fa5]+$
10、lastIndex
属性
记录上一次匹配的下标
const exc = 'hmdfc'
const reg = /\w/g // 只有全局模式才会有记忆
console.log(reg.exec(exc)) // ['h', index: 0, input: 'hmdfc', groups: undefined]
reg.lastIndex // 1
console.log(reg.exec(exc)) // ['m', index: 1, input: 'hmdfc', groups: undefined]
reg.lastIndex // 2
// ...
while(res = reg.exec(exc)) {
console.log(res)
// ['d', index: 2, input: 'hmdfc', groups: undefined]
// ['f', index: 3, input: 'hmdfc', groups: undefined]
// ['c', index: 4, input: 'hmdfc', groups: undefined]
}
参考文档:
学习视频: