一文搞懂 JavaScript 正则表达式(含基础 + 高级 + 模板 + 面试要点)

143 阅读4分钟

本文不是简单速查,而是一份可以反复阅读、用于复习与加深理解的系统笔记。内容包含基础语法、底层机制、常用模式、开发场景及高级特性。


目录

  1. 正则表达式是什么
  2. 创建正则的两种方式
  3. 字符匹配规则(基础)
  4. 边界符与位置匹配
  5. 量词系统(出现次数控制)
  6. 字符集与分组(重点)
  7. 修饰符 flags
  8. 正则常用方法(test、match、matchAll、replace 等)
  9. 贪婪与懒惰模式
  10. 回溯机制(面试高频)
  11. 零宽断言(Lookaround)
  12. Unicode 与转义(\u、\p{…})
  13. 常见开发场景正则(超实用)
  14. 常见坑 + 面试常考
  15. 复习脑图(结构化)

1. 正则表达式是什么?

正则表达式(Regular Expression, RegExp)是一种 基于规则的字符串模式匹配工具

可用于:

  • 字符串搜索(search)
  • 文本检测(表单校验)
  • 批量替换(replace)
  • 提取某部分内容(match、matchAll)
  • 清洗格式(trim、删除符号)

正则不是 JS 专用语言,而是一门“泛用文本处理语言”,但 JS 有自己的语法特性。


2. 创建正则的两种方式

2.1 字面量

const reg = /abc/i;

优点:简单直观
缺点:不能动态插入变量

2.2 构造函数

const reg = new RegExp("abc", "i");

可以使用变量:

const word = "hello";
new RegExp(word); // /hello/

注意:
在构造函数字符串中,`` 要再转义一次:

new RegExp("\d+") // 匹配数字

3. 字符匹配规则(基础必须掌握)

3.1 元字符(基础匹配符)

符号意义
.任意字符(不含换行)
\ddigit:数字
\D非数字
\wword:字母、数字、下划线
\W非 \w
\s空白字符
\S非空白字符

示例:

const reg = /\d\d\d/;
reg.test("123"); // true

4. 边界符与位置匹配(重要)

边界符用于让正则匹配“位置”,而不仅仅是字符。

符号作用
^匹配字符串开头
$匹配结尾
\b单词边界
\B非单词边界

示例 1:匹配完整三位数字

/^\d{3}$/

示例 2:匹配以 hello 开头

/^hello/

示例 3:单词边界

/\bcat\b/.test("I have a cat")   // true
/\bcat\b/.test("catt")           // false

5. 量词系统(出现次数控制)

量词含义
*0+
+1+
?0 或 1
{n}n 次
{n,}≥ n 次
{n,m}n 到 m 次

示例:匹配 6~16 位密码

/^\w{6,16}$/

6. 字符集与分组(重点)

6.1 字符集 []

表示某一位置可以是集中任意一个字符。

/[abc]/    // 匹配 a 或 b 或 c
/[0-9]/    // 匹配数字
/[A-Za-z]/ // 字母

6.2 排除字符集 [^]

/[^0-9]/    // 匹配非数字

6.3 分组 ()(regex 核心)

分组的作用:

  1. 捕获子串(在 match 中返回)
  2. 修改量词作用范围
  3. 反向引用
  4. 提取数据

例:匹配 2025-11-06

/(\d{4})-(\d{2})-(\d{2})/

结果:

[ "2025-11-06", "2025", "11", "06" ]

6.4 非捕获分组 (?:...)

用于仅改变规则,而不返回结果。

/(?:https?|ftp):///

7. 修饰符 flags(重要)

flag功能
g全局匹配
i忽略大小写
m多行匹配(^ 和 $ 匹配每行)
s. 匹配换行符
uUnicode 模式(处理 emoji)
y粘连模式

示例:

"hello".match(/l/g);  // ["l", "l"]

8. 正则常用方法(JS 侧重点)

8.1 test()

用于判断是否匹配

/\d+/.test("123")  // true

8.2 match()

用于提取内容

"abc123".match(/\d+/)   // ["123"]

8.3 matchAll()(强烈推荐)

遍历所有匹配 + 分组

[... "a1b2".matchAll(/(\d)/g)];

8.4 replace()

批量替换

"2025-11-06".replace(/-/g, "/");

8.5 split()

"a,b; c".split(/[,;]\s*/);

9. 贪婪与懒惰模式(高级)

默认情况下量词是“贪婪的”,能多匹配就多匹配。

例:

"aaa".match(/a+/)  // ["aaa"]

懒惰匹配:在量词后加 ?

"aaa".match(/a+?/) // ["a"]

常用于:

匹配 HTML 标签(非贪婪模式)

/<.+?>/g

10. 正则的回溯机制(面试常考)

回溯是正则引擎的重要机制:

  • 从左到右尝试
  • 尝试失败 → 回溯到上一步重新匹配
  • 回溯多是性能低的来源

例:

"aaaaab".match(/a+ab/) 

匹配过程从 a+ 尽可能多地吃字符,吃到最后发现无法匹配 ab,所以回溯一位,再尝试。

掌握回溯能:

  • 写出更高效的正则
  • 避免 ReDoS(正则拒绝服务攻击)

11. 零宽断言(Lookaround)

断言不消耗字符,只验证位置是否满足条件。

11.1 正向先行 (?=...)

/[a-z](?=\d)/gi

含义:匹配后面跟数字的字母

11.2 正向后行 (?<=...)

/(?<=$)\d+/  

匹配 $ 后面的数字

11.3 负向先行 (?!...)

匹配后面不是数字的字母

/[a-z](?!\d)/gi

11.4 负向后行 (?<!...)

匹配前面不是 $ 的数字:

/(?<!$)\d+/

断言在密码验证、输入校验中非常有价值。


12. Unicode 与转义(处理 emoji / 中文)

12.1 Unicode 模式 u

/\u{1F600}/u

匹配 emoji 😀

12.2 \p{…}(按类别匹配)

/\p{Emoji}/u

可以匹配全部 emoji(非常强大)


13. 常见开发场景正则(超实用)

13.1 手机号验证(中国)

/^1[3-9]\d{9}$/

13.2 邮箱验证

/^[\w.-]+@[\w.-]+.\w+$/

13.3 去除首尾空白

str.replace(/^\s+|\s+$/g, "");

13.4 匹配 HTML 标签(简单处理)

/<[^>]+>/g

13.5 提取 URL 参数

[... url.matchAll(/(\w+)=(\w+)/g)]

13.6 提取数字(包括负数)

/-?\d+(.\d+)?/

14. 常见坑(必须背)

❌ 1. "." 不会匹配换行

✔ 用 s 修饰符。

❌ 2. replace() 默认只替换第一个

✔ 用 g

❌ 3. 字面量无法插入变量

✔ new RegExp

❌ 4. 忽略大小写时,捕获组保留大小写

❌ 5. 贪婪匹配导致性能降低


15. 最终复习脑图(请收藏)

正则表达式
│
├── 基础匹配
│   ├── .   \d  \w  \s
│   ├── 字符集 [] [^]
│   ├── 边界 ^ $ \b
│
├── 量词
│   ├── * + ? {n}
│   ├── 贪婪 vs 懒惰
│
├── 分组 ()
│   ├── 捕获组
│   ├── 非捕获组 (?:)
│   ├── 反向引用
│
├── 修饰符 flags
│   ├── g i m s u y
│
├── API
│   ├── test
│   ├── match / matchAll
│   ├── replace
│   ├── split
│
├── 高级
│   ├── 回溯
│   ├── 零宽断言
│   ├── Unicode \p
│
└── 常用模板
    ├── 手机号
    ├── 邮箱
    ├── URL 参数
    ├── 去空白
    ├── HTML