创建正则表达式
// 字面量语法(推荐)——编译时确定,性能更好 const re1 = /\d+/g // 构造函数语法——运行时构建,适合动态模式 const re2 = new RegExp('\\d+', 'g') // 动态构建正则(需要转义特殊字符) function escapeRegex(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') } const keyword = escapeRegex(userInput) const searchRe = new RegExp(keyword, 'gi')
String 方法
match()
const str = 'test1 test2 test3' // 无 g 标志:返回第一个匹配(含捕获组) str.match(/test(\d)/) // → ['test1', '1', index: 0, input: ..., groups: undefined] // 有 g 标志:返回所有匹配字符串数组(不含捕获组详情) str.match(/test\d/g) // → ['test1', 'test2', 'test3'] // 有 g 标志时,捕获组信息丢失——改用 matchAll [...str.matchAll(/test(\d)/g)] // → [Match('test1','1'), Match('test2','2'), Match('test3','3')]
matchAll()(ES2020)
const text = '2026-01-01 和 2026-12-31' const dateRe = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/g for (const m of text.matchAll(dateRe)) { console.log(m.groups) // { year: '2026', month: '01', day: '01' } // { year: '2026', month: '12', day: '31' } }
replace() 和 replaceAll()
// 字符串替换 'hello world'.replace(/o/g, '0') // 'hell0 w0rld' // 捕获组引用($1, $2 或命名 $<name>) '2026-03-26'.replace( /(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/, '$<d>/$<m>/$<y>' ) // '26/03/2026' // 函数替换(动态) 'price: 100 dollars'.replace(/\d+/g, n => n * 1.1) // 'price: 110 dollars' // $& 表示整个匹配,$` 前面的文本,$' 后面的文本 'foo bar'.replace(/\w+/g, '[$&]') // '[foo] [bar]'
search()、split()、test()
// search:返回首个匹配的位置,无匹配返回 -1 'hello world'.search(/world/) // 6 // split:按正则分割 'a1b2c3d'.split(/\d/) // ['a','b','c','d'] ' hello world '.split(/\s+/).filter(Boolean) // ['hello', 'world'] // test:测试是否匹配,返回布尔值 /^\d{4}$/.test('2026') // true /^\d{4}$/.test('20261') // false
RegExp 方法
exec()
const re = /\d+/g let m while ((m = re.exec('a1 b22 c333')) !== null) { console.log(m[0], 'at', m.index) } // 1 at 1 // 22 at 4 // 333 at 8
WARNING带
g 标志的正则有 lastIndex 状态。用同一个正则对象多次调用 exec 或 test 时,记得注意 lastIndex 的位置,或者每次创建新的正则对象。ES2018 新特性
// 命名捕获组 const { groups } = '2026-03-26'.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/) console.log(groups) // { year: '2026', month: '03', day: '26' } // 后顾断言(lookbehind) '$100 €200'.match(/(?<=\$)\d+/g) // ['100'] // s 标志(dotAll) /foo.bar/s.test('foo\nbar') // true(. 匹配换行) // Unicode 属性转义 /\p{Letter}+/u.test('Hello') // true /\p{Script=Han}/u.test('汉') // true(匹配汉字)
小结
- 字面量
/pattern/flags是推荐写法;动态模式用new RegExp() match(g)返回所有字符串;matchAll(g)返回完整 Match 对象迭代器replace支持字符串($1引用)和函数(动态替换)- ES2018:命名捕获组、后顾断言、dotAll(
s)、Unicode 属性转义