主题
正则表达式
正则表达式用于描述“字符串模式”。它最适合做匹配、提取、校验和替换。
什么时候会用到
常见场景包括:
- 判断输入格式是否符合要求
- 从字符串中提取某一段内容
- 批量替换文本
- 按某种模式切分字符串
创建方式
字面量
js
const re = /abc/构造函数
js
const re = new RegExp('abc')如果模式来自变量拼接,通常使用 RegExp 构造函数更方便。
正则由什么组成
一条正则通常可以拆成两部分:
- 模式本体
- 标志位
js
const re = /abc/gi这里:
abc是模式g、i是标志位
最常见的基础语法
普通字符
js
;/abc/.test('abc123') // true元字符
js
/\d/.test('1') // true
/\w/.test('a') // true
/\s/.test(' ') // true
/./.test('x') // true常见的一组是:
\d:数字\w:字母、数字、下划线\s:空白符.:任意单个字符
对应的反义写法:
\D\W\S
锚点
锚点用于描述位置,而不是字符本身:
js
/^abc/.test('abc123') // true
/abc$/.test('123abc') // true
/\bcat\b/.test('cat dog') // true最常见的是:
^:开头$:结尾\b:单词边界
字符类
字符类用于表达“这一位可以是哪些字符”:
js
/[abc]/.test('b') // true
/[a-z]/.test('k') // true
/[0-9]/.test('8') // true
/[^abc]/.test('z') // true量词
量词用于表达“前面的模式出现多少次”:
js
/a*/.test('aaa') // true
/a+/.test('aaa') // true
/a?/.test('') // true
/a{3}/.test('aaa') // true
/a{2,5}/.test('aaaa') // true贪婪与惰性
量词默认是贪婪的,会尽量多吃字符:
js
;/.+/.exec('aaa')[0] // 'aaa'在量词后面加 ? 可以改成惰性匹配:
js
;/.+?/.exec('aaa')[0] // 'a'这在提取标签、括号内容、包裹片段时非常常见。
分组与捕获
捕获组
js
const match = /(\d{4})-(\d{2})-(\d{2})/.exec('2025-08-16')
console.log(match[1]) // 2025
console.log(match[2]) // 08
console.log(match[3]) // 16非捕获组
js
;/(?:abc)+/.test('abcabc') // true命名捕获组
js
const match = /(?<year>\d{4})-(?<month>\d{2})/.exec('2025-08')
console.log(match.groups.year) // 2025选择
使用 | 表示“满足其中一个”:
js
;/(cat|dog)/.test('dog') // true断言
断言用于表达“某个位置前后必须满足什么条件”,但本身不消费字符。
js
/\d+(?=px)/.exec('100px')[0] // '100'
/(?<=\$)\d+/.exec('$99')[0] // '99'常见的是:
(?=...):正向先行断言(?!...):正向否定断言(?<=...):反向先行断言(?<!...):反向否定断言
标志位
最常用的是:
g:全局匹配i:忽略大小写m:多行模式s:dotAllu:Unicodey:粘连模式
js
;/hello/gi.test('HELLO') // true常用方法
test
最适合做真假判断:
js
;/\d+/.test('abc123') // trueexec
最适合拿匹配结果和捕获组:
js
const match = /\d+/.exec('abc123')
console.log(match[0]) // '123'match
由字符串调用,适合快速拿结果:
js
'abc123'.match(/\d+/) // ['123']replace
js
'abc123'.replace(/\d+/g, '#') // 'abc#'split
js
'a,b,c'.split(/,/) // ['a', 'b', 'c']g 标志要特别注意
带 g 的正则在反复执行 test() 或 exec() 时,会受到 lastIndex 影响:
js
const re = /\d/g
console.log(re.test('1')) // true
console.log(re.test('1')) // false这里不是模式突然失效,而是正则对象自己记住了上一次匹配位置。
如果只是做一次性真假判断,通常不需要带 g。
正则适合和不适合的边界
适合:
- 固定格式校验
- 文本提取
- 批量替换
不太适合:
- 复杂语法解析
- 强语义结构分析
- 可读性要求极高的长规则
当一条正则已经长到难以解释时,通常应该考虑拆分逻辑或改用解析器。
使用建议
- 先明确目标是“判断、提取、替换”中的哪一种。
- 简单模式优先,别一开始就把所有规则塞进一条超长正则。
- 捕获组只在确实需要取值时再用。
- 遇到带
g的test()/exec()时,记得想到lastIndex。
