JavaScript中的正则表达式是处理字符串的强大工具,合理运用相关技巧可以大幅提升字符串操作的效率和代码的简洁性,下面介绍一些实用的高效使用技巧。

选择合适的正则创建方式
JavaScript中创建正则表达式有两种方式,分别是字面量和RegExp构造函数,不同的场景选择不同的方式能提升效率。
字面量方式适合正则模式固定的场景,它在代码解析阶段就会被编译,后续执行时不需要重复编译,性能更好。
// 字面量方式创建正则,匹配数字
const numReg = /d+/;
console.log(numReg.test('123')); // 输出 true
如果正则模式是动态生成的,或者需要拼接变量,就需要使用RegExp构造函数,此时需要注意对特殊字符进行转义。
// 动态生成正则,匹配指定后缀的文件名
const suffix = 'js';
const fileReg = new RegExp(`\w+\.${suffix}$`);
console.log(fileReg.test('index.js')); // 输出 true
合理使用正则标志位
正则的标志位可以改变匹配的行为,常用的标志位有g(全局匹配)、i(忽略大小写)、m(多行匹配)、s(dotAll模式)等,根据实际需求选择可以减少不必要的逻辑处理。
比如需要提取字符串中所有符合规则的子串时,使用g标志位配合match方法或者循环调用exec方法即可,不需要额外写循环判断逻辑。
const str = 'abc123def456ghi789'; const numReg = /d+/g; // 使用match方法直接获取所有匹配的数字 const nums = str.match(numReg); console.log(nums); // 输出 ["123", "456", "789"]
处理多行字符串时,使用m标志位可以让^和$匹配每一行的开头和结尾,而不只是整个字符串的开头和结尾。
const multiLineStr = `first line second line third line`; // 匹配每一行开头是s的内容 const lineReg = /^s.+/gm; console.log(multiLineStr.match(lineReg)); // 输出 ["second line"]
区分捕获组与非捕获组
正则中的圆括号默认是捕获组,会保存匹配到的内容,但是如果我们只是需要用圆括号来调整优先级或者做分组,不需要获取分组内容,使用非捕获组(?:)可以减少内存占用,提升性能。
const str = '2024-05-20';
// 捕获组方式,会保存年月日三个分组
const captureReg = /(d{4})-(d{2})-(d{2})/;
const captureResult = str.match(captureReg);
console.log(captureResult[1]); // 输出 2024
// 非捕获组方式,只做分组匹配,不保存分组内容
const nonCaptureReg = /(?:d{4})-(?:d{2})-(?:d{2})/;
const nonCaptureResult = str.match(nonCaptureReg);
console.log(nonCaptureResult[1]); // 输出 undefined
灵活运用零宽断言
零宽断言可以匹配某个位置,而不是具体的字符,适合需要基于前后内容做匹配的场景,比如匹配某个字符后面跟着特定内容,或者某个字符前面是指定内容的情况。
正向先行断言(?=)匹配后面跟着指定内容的位置,正向后行断言(?<=)匹配前面是指定内容的位置。
const priceStr = '商品价格是100元,优惠后是80元'; // 匹配数字后面跟着元的数字,即提取价格数字 const priceReg = /d+(?=元)/g; console.log(priceStr.match(priceReg)); // 输出 ["100", "80"] // 匹配前面是优惠后是的数字,即提取优惠后价格 const discountReg = /(?<=优惠后是)d+/; console.log(priceStr.match(discountReg)[0]); // 输出 80
正则性能优化技巧
复杂的正则如果写得不合理,很容易造成性能问题,尤其是处理长字符串的时候,需要注意以下几点优化方向。
- 尽量让正则的匹配路径更明确,避免过多的回溯,比如使用具体字符代替
.*这种模糊匹配。 - 对于可能多次使用的正则,提前定义好复用,不要每次使用都重新创建实例。
- 如果正则逻辑过于复杂,可以考虑拆分成多个简单的正则分步处理,比写一个超复杂的正则效率更高。
比如匹配HTML中的<div>标签内容,不要用/<div>.*</div>/这种写法,容易因为贪婪匹配导致回溯过多,可以改成更明确的匹配规则。
const htmlStr = '<div>content1</div><div>content2</div>'; // 优化前,贪婪匹配容易出问题 const badReg = /<div>.*</div>/g; console.log(htmlStr.match(badReg)); // 输出 ["<div>content1</div><div>content2</div>"] // 优化后,使用非贪婪匹配或者更明确的字符范围 const goodReg = /<div>[^<]+</div>/g; console.log(htmlStr.match(goodReg)); // 输出 ["<div>content1</div>", "<div>content2</div>"]
常用的正则工具方法搭配
JavaScript的字符串方法很多都支持正则参数,合理搭配可以简化代码逻辑。
| 方法名 | 作用 | 示例 |
|---|---|---|
| replace | 替换匹配到的字符串,支持正则替换,还可以用函数处理替换内容 | 'a1b2c3'.replace(/d+/g, '') 输出 'abc' |
| split | 按照正则匹配的规则分割字符串 | 'a1b2c3'.split(/d/) 输出 ['a','b','c',''] |
| search | 返回正则第一次匹配的位置索引,没有匹配到返回-1 | 'abc123'.search(/d/) 输出 3 |
比如需要把字符串中的驼峰命名转换成下划线命名,用replace配合正则和回调函数可以一行代码实现。
const camelStr = 'getUserName'; const snakeStr = camelStr.replace(/[A-Z]/g, (match) => '_' + match.toLowerCase()); console.log(snakeStr); // 输出 get_user_name
JavaScript正则表达式RegExp字符串匹配正则优化修改时间:2026-06-23 06:21:39