JavaScript正则表达式实战指南:从基础到高级技巧
全面解析修饰符、元字符、分组捕获等核心概念,附可运行的代码示例
正则表达式是文本处理的瑞士军刀,本文通过可验证的代码示例,帮你构建系统性的正则知识体系。
一、基础方法使用与陷阱修正
1.1 test() 与 exec() 的全局匹配陷阱
问题:使用g修饰符时,正则对象的lastIndex属性会导致后续匹配位置偏移
修正方案:非必要不使用g,或每次重置lastIndex=0
const hd = "asklfdhaf.com";
const reg = /a/g;
// test() 受 lastIndex 影响
console.log(reg.test(hd)); // true(lastIndex变为1)
console.log(reg.test(hd)); // true(从位置1继续匹配)
console.log(reg.test(hd)); // false(匹配结束)
// 重置 lastIndex 保证结果稳定
reg.lastIndex = 0;
console.log(reg.exec(hd)); // ["a", index:0](正确返回首个匹配)
1.2 字符串方法的安全用法
// replace() 全局替换
console.log(hd.replace(reg, "b")); // "bsklfdhbf.com"(所有a被替换)
// match() 返回所有匹配结果
reg.lastIndex = 0; // 重置防止污染
console.log(hd.match(reg)); // ["a", "a"](不改变lastIndex)
二、修饰符:控制匹配模式的关键
2.1 核心修饰符对比
| 修饰符 | 作用 | 示例场景 |
|---|---|---|
i | 忽略大小写 | /a/i 匹配 "A" 和 "a" |
g | 全局匹配 | 替换所有符合项 |
m | 多行模式(^/$匹配每行) | 日志文件分析 |
// i修饰符实现大小写不敏感替换
const str = "a球员突破,A球员射门,A球员进球了!";
const regA = /a/ig;
console.log(str.replace(regA, "b"));
// "b球员突破,b球员射门,b球员进球了!"
三、元字符:精准定义匹配规则
3.1 边界控制符
// \b 匹配单词边界(避免误匹配player中的play)
const words = "I play the player in the game";
const regB = /\bplay\b/g;
console.log(words.replace(regB, "control"));
// "I control the player in the game"
// ^/$ 定义字符串边界
const regC = /^a/;
console.log(regC.test("abc")); // true(以a开头)
console.log(regC.test("bca")); // false(不以a开头)
3.2 量词:控制匹配次数
const regD = /^a{1,4}$/; // 匹配1到4个连续的a
console.log(regD.test("a")); // true
console.log(regD.test("aaaa")); // true
console.log(regD.test("")); // false(0次不符合)
console.log(regD.test("bbbb")); // false(非a字符)
3.3 字符类:定义匹配集合
| 类型 | 正则 | 等价形式 | 作用 |
|---|---|---|---|
| 数字 | \d | [0-9] | 匹配数字字符 |
| 非数字 | \D | [^0-9] | 匹配非数字字符 |
| 单词字符 | \w | [a-zA-Z0-9_] | 匹配字母数字下划线 |
| 非单词字符 | \W | [^\w] | 匹配非单词字符 |
| 空白符 | \s | [\t\r\n\v\f] | 匹配空白符 |
| 非空白符 | \S | [^\s] | 匹配非空白符 |
// 示例:邮箱格式简易验证
const emailReg = /^[\w-]+@\w+.[a-z]{2,}$/i;
console.log(emailReg.test("test@example.com")); // true
四、高级技巧:分组捕获与引用
4.1 分组在数据提取中的应用
// 日期格式转换(YYYY-MM-DD → MM/DD/YYYY)
const regF = /(\d{4})-(\d{2})-(\d{2})/;
const testStr = "今天的日期是2024-06-06";
// $n引用分组:$1=2024, $2=06, $3=06
console.log(testStr.replace(regF, "$2/$3/$1"));
// "今天的日期是06/06/2024"
4.2 非捕获分组优化性能
当不需要提取分组内容时,使用(?:)避免内存占用:
// 仅分组不捕获
const optimReg = /(?:\d{4})-(?:\d{2})-(\d{2})/;
console.log(testStr.match(optimReg));
// 只捕获最后两位日期 ["2024-06-06", "06"]