正则表达式大全-匹配的艺术

一、什么是正则表达式?

正则表达式(Regular Expression)是一种强大的文本匹配模式,用于检索、验证或替换符合特定规则的字符串。

1.1 正则表达式能做什么?

1
2
3
4
5
6
7
8
9
10
┌─────────────────────────────────────────────────────────────────┐
│ 正则表达式用途 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 🔍 验证 → 邮箱、手机号、身份证等格式验证 │
│ 🔎 搜索 → 从大量文本中提取需要的内容 │
│ 🔄 替换 → 批量修改、格式化文本 │
│ 📝 提取 → 提取URL、标签、数字等特定内容 │
│ │
└─────────────────────────────────────────────────────────────────┘

1.2 常见使用场景

场景 示例
表单验证 邮箱、手机号、密码强度
数据提取 从日志中提取时间、IP
文本替换 批量格式化、清理数据
爬虫 提取网页中的链接、图片

二、基础语法

2.1 元字符

元字符 说明 示例
. 任意单个字符(除换行) a.c → abc, aXc
\d 任意数字 \d → 1, 9
\D 任意非数字 \D → a, @
\w 字母、数字、下划线 \w+ → hello_123
\W 非字母数字下划线 \W → @, #
\s 空白字符(空格 tab 换行) \s+ → 空格
\S 非空白字符 \S+ → hello
\b 单词边界 \bhello\b
\B 非单词边界
^ 字符串开头 ^hello
$ 字符串结尾 world$

2.2 字符类

1
2
3
4
5
6
7
[abc]      # 匹配a、b、c中的任意一个
[^abc] # 匹配除了a、b、c的任意字符
[a-z] # 匹配a到z的任意字符
[A-Z] # 匹配A到Z
[0-9] # 匹配0到9
[a-zA-Z] # 匹配所有字母
[a-zA-Z0-9] # 匹配字母和数字

示例:

1
2
3
[aeiou]         # 匹配元音字母
[0-9]{3} # 匹配3位数字
[a-zA-Z]{3,} # 至少3个字母

2.3 量词

量词 说明 示例
* 0次或多次 ab* → a, ab, abb
+ 1次或多次 ab+ → ab, abb
? 0次或1次 ab? → a, ab
{n} 恰好n次 a{3} → aaa
{n,} 至少n次 a{2,} → aa, aaa
{n,m} n到m次 a{2,4} → aa, aaa, aaaa
*? 0次或多次(非贪婪)
+? 1次或多次(非贪婪)

三、常用正则表达式

3.1 数字相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 整数
^-?\d+$

# 正整数
^[1-9]\d*$

# 负整数
^-[1-9]\d*$

# 浮点数
^-?\d+\.\d+$

# 正浮点数
^[1-9]\d*\.\d+$|^0\.\d+[1-9]$

# 数字(可带千分位)
^[\d,]+$

# 货币金额(两位小数)
^\d{1,3}(,\d{3})*(\.\d{2})?$

3.2 中文相关

1
2
3
4
5
6
7
8
9
10
11
# 中文汉字
[\u4e00-\u9fa5]

# 中文姓名(2-4个汉字)
^[\u4e00-\u9fa5]{2,4}$

# 中文地址
[\u4e00-\u9fa5]+省[\u4e00-\u9fa5]+市[\u4e00-\u9fa5]+区

# 中文句子
[\u4e00-\u9fa5]+

3.3 英文相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 纯英文
^[a-zA-Z]+$

# 英文和数字
^[a-zA-Z0-9]+$

# 小写英文
^[a-z]+$

# 大写英文
^[A-Z]+$

# 英文、数字、下划线
^[a-zA-Z0-9_]+$

3.4 联系方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 中国手机号
^1[3-9]\d{9}$

# 固定电话
^0\d{2,3}-?\d{7,8}$

# 中国身份证号(18位)
^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$

# 邮箱
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

# QQ号
^[1-9]\d{4,10}$

# 微信号
^[a-zA-Z][a-zA-Z0-9_-]{5,19}$

3.5 URL与域名

1
2
3
4
5
6
7
8
9
10
11
# HTTP/HTTPS URL
^https?:\/\/([\w\-]+\.)+[\w\-]+(\/[\w\-\.~!@#$%^&*+?:\\\[\]=.;,':"/\\|]*)?$

# 域名
^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z]{2,})+$

# IP地址
^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$

# IPv6地址
^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$

3.6 日期与时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 日期(YYYY-MM-DD)
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$

# 日期(YYYY/MM/DD)
^\d{4}\/(0[1-9]|1[0-2])\/(0[1-9]|[12]\d|3[01])$

# 日期(YYYYMMDD)
^\d{8}$

# 时间(HH:MM:SS)
^([01]\d|2[0-3]):[0-5]\d:[0-5]\d$

# 时间(HH:MM)
^([01]\d|2[0-3]):[0-5]\d$

# 日期时间(ISO格式)
^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z?$

3.7 密码验证

1
2
3
4
5
6
7
8
# 密码(6-18位,字母数字)
^[a-zA-Z0-9]{6,18}$

# 密码(必须包含字母和数字)
^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$

# 密码(必须包含大小写字母、数字、特殊字符)
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$

3.8 HTML相关

1
2
3
4
5
6
7
8
9
10
11
# HTML标签
<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)

# HTML标签(简化)
<[^>]+>

# 图片标签
<img\s+[^>]*src=["']([^"']+)["'][^>]*>

# 链接标签
<a\s+[^>]*href=["']([^"']+)["'][^>]*>([^<]+)<\/a>

四、Python中使用正则

4.1 基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import re

# 匹配
pattern = r'\d+'
text = 'abc123def456'
result = re.search(pattern, text)
print(result.group()) # 123

# 查找全部
result = re.findall(r'\d+', text)
print(result) # ['123', '456']

# 替换
result = re.sub(r'\d+', 'X', text)
print(result) # abcXdefX

# 分割
result = re.split(r'\d+', text)
print(result) # ['abc', 'def', '']

4.2 匹配对象

1
2
3
4
5
6
7
8
9
10
11
12
13
import re

pattern = r'(\d{4})-(\d{2})-(\d{2})'
text = '2026-02-13'

match = re.search(pattern, text)
if match:
print(match.group()) # 2026-02-13
print(match.group(1)) # 2026
print(match.group(2)) # 02
print(match.group(3)) # 13
print(match.groups()) # ('2026', '02', '13')
print(match.span()) # (0, 10)

4.3 编译正则

1
2
3
4
5
6
7
8
import re

# 预编译提高性能
pattern = re.compile(r'\d{4}-\d{2}-\d{2}')

# 使用
result = pattern.findall('2026-02-13 2025-01-01')
print(result) # ['2026-02-13', '2025-01-01']

4.4 命名分组

1
2
3
4
5
6
7
8
9
10
import re

pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
text = '2026-02-13'

match = re.search(pattern, text)
print(match.group('year')) # 2026
print(match.group('month')) # 02
print(match.group('day')) # 13
print(match.groupdict()) # {'year': '2026', 'month': '02', 'day': '13'}

4.5 实战示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import re

# 提取邮箱
emails = 'test@example.com, user@domain.org, invalid@'
result = re.findall(r'[\w.-]+@[\w.-]+\.\w+', emails)
print(result) # ['test@example.com', 'user@domain.org']

# 提取URL
text = '访问 https://example.com 和 http://test.org'
result = re.findall(r'https?://[\w\-.]+', text)
print(result) # ['https://example.com', 'http://test.org']

# 验证手机号
phone = '13812345678'
pattern = r'^1[3-9]\d{9}$'
if re.match(pattern, phone):
print('有效手机号')

# 提取HTML内容
html = '<a href="https://example.com">点击</a>'
result = re.search(r'href=["\']([^"\']+)["\'][^>]*>([^<]+)<', html)
if result:
print(result.group(1)) # https://example.com
print(result.group(2)) # 点击

# 格式化日期
date = '2026/02/13'
result = re.sub(r'(\d{4})/(\d{2})/(\d{2})', r'\1-\2-\3', date)
print(result) # 2026-02-13

五、JavaScript中使用正则

5.1 基本操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 创建正则
const pattern = /\d+/;
const pattern2 = new RegExp('\\d+');

// test() - 测试是否匹配
const str = 'abc123';
console.log(/\d+/.test(str)); // true

// exec() - 获取匹配结果
const result = /\d+/.exec(str);
console.log(result[0]); // 123

// match() - 查找全部
console.log('abc123def456'.match(/\d+/g)); // ['123', '456']

// replace() - 替换
console.log('abc123'.replace(/\d+/, 'X')); // abcX

// split() - 分割
console.log('a1b2c'.split(/\d+/)); // ['a', 'b', 'c']

5.2 常用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 验证邮箱
function validateEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

// 验证手机号
function validatePhone(phone) {
return /^1[3-9]\d{9}$/.test(phone);
}

// 提取URL
const text = '访问 https://example.com 和 http://test.org';
const urls = text.match(/https?:\/\/[\w\-.]+/g);
console.log(urls); // ['https://example.com', 'http://test.org']

// 提取日期
const dateStr = '2026-02-13';
const [, year, month, day] = dateStr.match(/(\d{4})-(\d{2})-(\d{2})/);
console.log(year, month, day); // 2026 02 13

// 格式化手机号
function formatPhone(phone) {
return phone.replace(/(\d{3})(\d{4})(\d{4})/, '$1****$3');
}
console.log(formatPhone('13812345678')); // 138****5678

// 去除HTML标签
function stripTags(html) {
return html.replace(/<[^>]+>/g, '');
}
console.log(stripTags('<p>Hello</p>')); // Hello

5.3 零宽断言

1
2
3
4
5
6
7
8
9
10
11
// 正向先行断言 (?=)
console.log('a1b2c3'.replace(/\d(?=[a-z])/g, 'X')); // aXbXcX

// 负向先行断言 (?!)
console.log('a1b2c3'.replace(/\d(?![a-z])/g, 'X')); // a1b2cX

// 正向后行断言 (?<=)
console.log('a1b2c3'.replace(/(?<=[a-z])\d/g, 'X')); // aXbXcX

// 负向后行断言 (?<!)
console.log('a1b2c3'.replace(/(?<![a-z])\d/g, 'X')); // a1b2cX

六、Linux命令行中使用

6.1 grep

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 基本匹配
grep "error" log.txt

# 正则匹配
grep -E "\d{4}-\d{2}-\d{2}" log.txt

# 显示行号
grep -n "error" log.txt

# 反向匹配
grep -v "debug" log.txt

# 显示匹配的行及其后3行
grep -A 3 "error" log.txt

# 显示匹配的行及其前3行
grep -B 3 "error" log.txt

# 显示匹配的行及其前后3行
grep -C 3 "error" log.txt

# 忽略大小写
grep -i "error" log.txt

# 递归搜索
grep -r "error" /var/log/

# 只显示文件名
grep -l "error" *.txt

6.2 sed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 替换
sed 's/old/new/' file.txt

# 全局替换
sed 's/old/new/g' file.txt

# 指定行替换
sed '5s/old/new/' file.txt

# 多行替换
sed '1,5s/old/new/g' file.txt

# 删除匹配行
sed '/error/d' file.txt

# 显示特定行
sed -n '1,10p' file.txt

# 插入行
sed '1i\Header' file.txt

# 追加行
sed '1a\New line' file.txt

6.3 awk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 提取字段
awk '{print $1}' file.txt

# 指定分隔符
awk -F',' '{print $1}' file.csv

# 条件过滤
awk '/error/ {print}' log.txt

# 条件判断
awk '{if ($3 > 80) print $0}' file.txt

# 计算
awk '{sum+=$1} END {print sum}' file.txt

七、实战案例

7.1 表单验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 完整的表单验证
const validators = {
// 邮箱
email: (value) => {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)
? '' : '请输入有效的邮箱地址';
},

// 手机号
phone: (value) => {
return /^1[3-9]\d{9}$/.test(value)
? '' : '请输入有效的手机号';
},

// 密码
password: (value) => {
if (value.length < 8) return '密码至少8位';
if (!/[A-Z]/.test(value)) return '密码需包含大写字母';
if (!/[a-z]/.test(value)) return '密码需包含小写字母';
if (!/\d/.test(value)) return '密码需包含数字';
return '';
},

// 身份证
idCard: (value) => {
return /^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/.test(value)
? '' : '请输入有效的身份证号';
}
};

7.2 数据提取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import re

# 提取日志中的时间
log = '2026-02-13 10:30:45 ERROR: Connection failed'
time = re.search(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}', log)
print(time.group()) # 2026-02-13 10:30:45

# 提取IP地址
text = 'Server IP: 192.168.1.100, Client IP: 10.0.0.1'
ips = re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', text)
print(ips) # ['192.168.1.100', '10.0.0.1']

# 提取JSON中的值
json_str = '{"name": "John", "age": 30}'
name = re.search(r'"name":\s*"([^"]+)"', json_str)
print(name.group(1)) # John

# 提取手机号
text = '联系电话:13812345678 或 13998765432'
phones = re.findall(r'1[3-9]\d{9}', text)
print(phones) # ['13812345678', '13998765432']

7.3 文本替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import re

# 统一日期格式
text = '2026/02/13, 2025-12-01, 2024.01.15'
result = re.sub(r'(\d{4})[/\.](\d{2})[/\.](\d{2})', r'\1-\2-\3', text)
print(result) # 2026-02-13, 2025-12-01, 2024-01-15

# 手机号脱敏
text = '手机号:13812345678'
result = re.sub(r'(\d{3})\d{4}(\d{4})', r'\1****\2', text)
print(result) # 手机号:138****5678

# 去除多余空格
text = 'Hello World !'
result = re.sub(r'\s+', ' ', text)
print(result) # Hello World !

# 提取并格式化
text = '价格:299元,原价399元'
result = re.sub(r'原价(\d+)元', r'原价\1元(省\1元)', text)
print(result) # 价格:299元,原价399元(省399元)

八、速查表

8.1 元字符

字符 说明
. 任意字符
\d 数字
\D 非数字
\w 字母数字下划线
\W 非字母数字下划线
\s 空白字符
\S 非空白字符
^ 开头
$ 结尾

8.2 量词

量词 说明
* 0或多个
+ 1或多个
? 0或1个
{n} n个
{n,} n或多个
{n,m} n到m个

8.3 字符类

字符类 说明
[abc] a或b或c
[^abc] 非a非b非c
[a-z] a到z
[0-9] 0到9

8.4 分组

分组 说明
(abc) 捕获组
(?:abc) 非捕获组
(?<name>abc) 命名组

九、在线工具

工具 地址
Regex101 https://regex101.com/
Regexr https://regexr.com/
RegExpal https://www.regexpal.com/

参考资料


持续更新中…欢迎收藏!

#正则表达式 #Regex #字符串匹配 #教程


正则表达式大全-匹配的艺术
https://r0f2.my/post/21-regular-expression-guide/
作者
JA
发布于
2026年2月13日
许可协议