javascript 正则表达式是 JS 内置的文本匹配工具 全称 Regular Expression 主要用来对字符串做校验 查找 替换 提取子串这类操作 在表单验证 手机号邮箱校验 文本清洗 数据提取场景使用非常频繁 在 JS 里面创建正则表达式一共有两种写法 一种是字面量写法 斜杠包裹正则内容 后面追加修饰符 另一种是 RegExp 构造函数写法 适合正则规则需要动态拼接的场景 很多初学者容易混淆元字符 量词 分组 修饰符的用法 还经常踩贪婪匹配 转义字符 全局匹配 lastIndex 偏移这些坑 正则本身属于独立语法体系 虽然写在 javascript 里面 但是规则和其他语言正则大体相似 同时保留 JS 引擎特有的行为特性 下面从创建方式 基础元字符 量词 分组 修饰符 常用 API 实战案例 排错要点逐层深度讲解。
两种创建方式
第一种 字面量创建
写法格式 / 正则规则 / 修饰符
优点 代码简洁 引擎在代码加载阶段就编译正则 性能更好 适合固定不变的正则
缺点 规则不能动态拼接 字符串变量无法直接嵌入
第二种 RegExp 构造函数创建
写法格式 new RegExp 正则字符串 修饰符
优点 支持动态拼接正则字符串 适合运行时才确定匹配规则的场景
缺点 字符串里面的反斜杠需要二次转义 容易写漏转义导致报错
基础元字符对照表
| 元字符 | 作用说明 |
|---|---|
| . | 匹配除换行符之外任意单个字符 |
| \d | 匹配数字 等价 0 到 9 |
| \D | 匹配非数字 |
| \w | 匹配字母数字下划线 |
| \W | 匹配非字母数字下划线 |
| \s | 匹配空白字符 空格 制表符 换行 |
| \S | 匹配非空白字符 |
| ^ | 匹配字符串开头 |
| $ | 匹配字符串结尾 |
| [] | 字符集合 匹配括号内任意一个字符 |
| [^] | 反向字符集 匹配不在括号内的字符 |
量词与匹配模式
量词用来控制前面单元重复匹配次数
| 量词 | 含义 |
|---|---|
| * | 匹配 0 次或者多次 |
| + | 匹配 1 次或者多次 |
| ? | 匹配 0 次或者 1 次 |
| {n} | 固定匹配 n 次 |
| {n,} | 至少匹配 n 次 |
| {n,m} | 匹配 n 到 m 次 |
贪婪与非贪婪
默认是贪婪匹配 会尽可能多匹配字符 在量词后面加问号 切换成非贪婪匹配 尽可能少匹配字符 这是 javascript 正则表达式高频考点
分组 捕获组与非捕获组
分组使用小括号 作用是把一段规则当成整体 同时可以捕获匹配到的内容
捕获组 小括号默认就是捕获组 匹配成功之后可以通过索引拿到分组内容
非捕获组 写法是 (?: 规则) 只做分组 不保存捕获结果 适合不需要提取内容 只需要整体重复的场景
还有正向预查 负向预查 也就是断言 用来判断前后文本是否满足条件 不会占用匹配结果 适合复杂边界校验
修饰符清单
| 修饰符 | 功能 |
|---|---|
| g | 全局匹配 匹配所有符合项 不是只匹配第一个 |
| i | 忽略大小写 |
| m | 多行模式 让 ^ 和 $ 匹配每一行的行首行尾 |
| s | dotAll 模式 让点号可以匹配换行符 |
| u | 开启 Unicode 模式 处理四字节 Unicode 字符 |
| y | 粘连匹配 从 lastIndex 位置连续匹配 |
javascript 正则核心 API
第一 test 方法
正则对象调用 传入字符串 返回布尔值 只判断是否匹配成功 表单校验最常用
第二 exec 方法
正则对象调用 返回匹配详情数组 包含捕获组 索引 原字符串 带 g 修饰符的时候 每次调用会自动更新 lastIndex 连续调用可以依次取出所有匹配项
第三 字符串方法支持正则
match 匹配返回结果数组
replace 按照正则规则替换文本
search 返回第一个匹配位置索引
split 按照正则规则分割字符串
实战常用案例
手机号校验 规则匹配 1 开头 第二位 3 到 9 后面总共 11 位数字
邮箱校验 匹配用户名部分 @ 域名部分 包含点号
去除文本多余空格 匹配连续空白 替换成单个空格
提取字符串里面所有数字 搭配 g 全局修饰符遍历全部匹配项
踩坑排查清单
第一 带 g 修饰符 test 或者 exec 的时候 lastIndex 会保留上次位置 连续校验同一个字符串会出现真假交替 这个是 JS 正则非常经典的坑
第二 RegExp 构造函数里面 反斜杠要写两个 比如 \d 要写成 \d
第三 忘记加 ^ 和 $ 校验的时候会出现只要字符串里面包含符合片段就判定通过 不是完整匹配
第四 点号默认不匹配换行符 多行文本需要加 s 修饰符
第五 字符集里面特殊字符不需要额外转义 但是部分符号在外面需要转义 容易混淆
综合来看 javascript 正则表达式核心就是元字符定义匹配单元 量词控制重复次数 分组提取内容 修饰符改变匹配行为 配合 test exec match replace 这些 API 完成文本处理 学习的时候优先掌握基础元字符和量词 再进阶学习分组断言 重点记住 g 修饰符带来的 lastIndex 特性 这个是 JS 正则和其他语言差异比较明显的地方
【常见问题】
问题 1 javascript 正则表达式里面 g 修饰符为什么多次 test 结果不稳定
回答 1 javascript 正则表达式开启 g 修饰符之后 每次匹配会更新 lastIndex 指针 下一次匹配会从上次结束位置继续查找 所以连续 test 同一个字符串会出现结果交替变化 可以每次重置 lastIndex 为 0 解决
问题 2 javascript 正则表达式字面量和 RegExp 构造函数应该优先选哪个
回答 2 javascript 正则表达式如果规则固定优先使用字面量写法 性能更好 代码简洁 如果规则需要动态拼接变量 才选择 RegExp 构造函数写法
问题 3 javascript 正则表达式 ^ 和 $ 是不是默认匹配整段字符串全部内容
回答 3 javascript 正则表达式 ^ 代表字符串开头 $ 代表字符串结尾 只有同时加上 ^ 和 $ 才是完整全匹配 不加的话只要字符串内部存在匹配片段就会命中
问题 4 javascript 正则表达式 贪婪匹配和非贪婪匹配区别是什么
回答 4 javascript 正则表达式默认贪婪匹配 尽可能多匹配字符 在量词后面加问号就切换非贪婪匹配 尽可能少匹配字符 提取短片段的时候经常需要使用非贪婪模式
【免责申明】
本内容基于 ECMAScript 标准对 javascript 正则表达式进行语法科普 不同浏览器和 JS 引擎版本对部分高阶特性支持存在差异 教程仅作为前端学习参考 生产项目复杂正则建议在目标运行环境做兼容性测试 本内容不替代官方 ECMA 标准文档 不保证所有极端场景正则行为完全一致


