Back to Blog
2026-02-22ToolBox Team

正则表达式完全指南 - 从入门到精通

🔧 返回工具箱 | Back to Tools

浏览所有工具 | View All Tools
regexpatternstext-processingjavascript

正则表达式完全指南 - 从入门到精通

正则表达式被称为"程序员的瑞士军刀"。掌握它,你可以用一行代码完成繁琐的字符串处理;不掌握它,则会陷入无尽的字符串拼接和循环地狱。

1. 正则表达式基础

什么是正则表达式?

正则表达式是一种模式匹配语言,用于在文本中查找、替换和验证字符串。

// JavaScript 中的正则表达式
const regex1 = /hello/;              // 字面量写法
const regex2 = new RegExp('hello');  // 构造函数写法

// 匹配
console.log(/hello/.test('hello world'));  // true
console.log(/hello/.test('goodbye'));      // false

基本语法元素

元素 含义 示例
. 任意字符(除换行) a.b 匹配 "aab"、"acb"
* 前面元素出现 0 次或多次 a*b 匹配 "b"、"ab"、"aab"
+ 前面元素出现 1 次或多次 a+b 匹配 "ab"、"aab",不匹配 "b"
? 前面元素出现 0 次或 1 次 a?b 匹配 "b"、"ab"
^ 字符串开头 ^hello 只匹配字符串开头的 "hello"
$ 字符串结尾 world$ 只匹配字符串结尾的 "world"
[abc] 字符类:匹配任意一个 [aeiou] 匹配任意元音字母
[^abc] 反向字符类 [^0-9] 匹配任何非数字
(abc) 分组 (ab)+ 匹配 "ab"、"abab"
| cat|dog 匹配 "cat" 或 "dog"

实战例子

// 验证邮箱
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(emailRegex.test('alice@example.com'));  // true
console.log(emailRegex.test('invalid.email'));      // false

// 提取所有数字
const text = 'I have 2 cats and 3 dogs';
const numbers = text.match(/\d+/g);
console.log(numbers);  // ['2', '3']

// 替换所有空格
console.log('hello world'.replace(/\s+/g, '-'));  // 'hello-world'

2. 常见正则表达式模式

电子邮件验证

const email = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;

console.log(email.test('alice@example.com'));      // true
console.log(email.test('bob.smith@company.co.uk')); // true
console.log(email.test('invalid@'));                // false

URL 验证

const urlRegex = /^(https?:\/\/)?([\w-]+\.)+[a-z]{2,}(\/.*)?$/i;

console.log(urlRegex.test('https://example.com'));           // true
console.log(urlRegex.test('https://sub.domain.com/path'));   // true
console.log(urlRegex.test('not a url'));                     // false

手机号码验证(简单)

// 中国手机号
const phoneRegex = /^1[3-9]\d{9}$/;

console.log(phoneRegex.test('13812345678'));  // true
console.log(phoneRegex.test('12345678901'));  // false

密码强度

// 至少 8 个字符,包含大小写字母和数字
const strongPassword = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;

console.log(strongPassword.test('WeakPwd'));       // false
console.log(strongPassword.test('StrongPwd123')); // true

解释

  • (?=.*[a-z]) 正向前瞻,确保包含小写字母
  • (?=.*[A-Z]) 正向前瞻,确保包含大写字母
  • (?=.*\d) 正向前瞻,确保包含数字
  • .{8,} 至少 8 个字符

3. JavaScript 中的正则表达式方法

字符串方法

const text = 'hello world hello';

// match 返回匹配数组
console.log(text.match(/hello/g));     // ['hello', 'hello']
console.log(text.match(/\w+/g));       // ['hello', 'world', 'hello']

// search 返回索引
console.log(text.search(/world/));     // 6

// replace 替换匹配
console.log(text.replace(/hello/, 'hi'));    // 'hi world hello' (仅第一个)
console.log(text.replace(/hello/g, 'hi'));   // 'hi world hi' (全部)

// split 按模式分割
console.log('a1b2c3'.split(/\d/));           // ['a', 'b', 'c', '']

// includes 检查是否包含(简单匹配)
console.log('hello123'.match(/\d+/));        // ['123']

正则对象方法

const regex = /(\w+)@(\w+)\.(\w+)/;
const email = 'alice@example.com';

// exec 逐个返回匹配
const match = regex.exec(email);
console.log(match);
/* 输出:
[
  'alice@example.com',  // 完整匹配
  'alice',              // 第 1 个捕获组
  'example',            // 第 2 个捕获组
  'com'                 // 第 3 个捕获组
]
*/

// test 返回布尔值
console.log(regex.test(email));  // true

4. 高级技巧

分组与捕获

// 提取日期组件
const dateRegex = /(\d{4})-(\d{2})-(\d{2})/;
const date = '2026-02-27';

const [full, year, month, day] = dateRegex.exec(date);
console.log(`年: ${year}, 月: ${month}, 日: ${day}`);
// 输出:年: 2026, 月: 02, 日: 27

非捕获分组

// 有时我们只想分组,而不想捕获
const phoneRegex = /(?:\+86)?1[3-9]\d{9}/;

// 使用 (?:...) 不会在匹配中创建捕获组
console.log('13812345678'.match(phoneRegex));   // ['13812345678']
console.log('+8613812345678'.match(phoneRegex)); // ['+8613812345678']

前瞻与后瞻

// 正向前瞻:匹配后面是 "world" 的 "hello"
const text = 'hello world vs hello there';
console.log(text.match(/hello(?=\s+world)/));  // ['hello']

// 负向前瞻:匹配后面不是数字的字符
console.log('a1b2c'.match(/[a-z](?!\d)/g));    // ['c']

字符串替换与捕获组

// 交换名字顺序:John Smith → Smith, John
const name = 'John Smith';
const swapped = name.replace(/(\w+)\s+(\w+)/, '$2, $1');
console.log(swapped);  // 'Smith, John'

// 使用函数进行复杂替换
const text = 'Price: $100, Qty: 2, Total: $200';
const result = text.replace(/\$(\d+)/g, (match, number) => {
  return `¥${number * 7}`;  // 假设 1$ = 7¥
});
console.log(result);  // 'Price: ¥700, Qty: 2, Total: ¥1400'

5. 性能优化

避免灾难性回溯

// ❌ 不好:容易导致灾难性回溯
const badRegex = /(a+)+b/;

// ✅ 好:直接、高效
const goodRegex = /a+b/;

当输入 "aaaaaaaaaaac"(无 b)时,badRegex 会尝试数百万种组合才放弃,导致 CPU 跑满。

使用锚点限制匹配范围

// ❌ 回溯多次
const slow = /.*world/;

// ✅ 减少回溯
const fast = /^.*world$/;  // 从开头限制搜索范围

预编译正则表达式

// ❌ 每次调用都编译
function validate(email) {
  return /[a-z]+@[a-z]+\.\w+/.test(email);
}

// ✅ 预编译,重复利用
const emailRegex = /[a-z]+@[a-z]+\.\w+/;
function validate(email) {
  return emailRegex.test(email);
}

6. 实战应用

验证和清理用户输入

function sanitizeFileName(fileName) {
  // 移除特殊字符,只保留字母、数字、下划线和点
  return fileName.replace(/[^a-zA-Z0-9._-]/g, '');
}

console.log(sanitizeFileName('my-file@#$%.txt'));  // 'my-file%.txt'

解析结构化文本

// 解析日志行
const logRegex = /\[(\d{2}:\d{2}:\d{2})\] \[(\w+)\] (.+)/;
const logLine = '[14:25:30] [ERROR] Database connection failed';

const [, time, level, message] = logRegex.exec(logLine);
console.log({ time, level, message });
// { time: '14:25:30', level: 'ERROR', message: 'Database connection failed' }

在线测试工具

正则表达式工具 中可以实时测试正则表达式、查看匹配结果和性能分析。


相关工具推荐