一、引言:为什么需要正则表达式和 JSON?
在现代编程中,正则表达式 和JSON是处理文本与数据的两大核心工具:
|-------------|-----------------------------------|
| 工具 | 核心用途 |
| ✅ 正则表达式 | 高效匹配、提取、替换复杂文本模式(如邮箱、手机号、日志解析) |
| ✅ JSON | 轻量级数据交换格式,广泛用于 Web API、配置文件、数据存储等 |
Python 提供了强大的内置模块:
re
模块:处理正则表达式json
模块:实现 JSON 的编码与解码
掌握它们,你将具备数据清洗、接口通信、日志分析等关键能力!
二、正则表达式(Regular Expressions)
1. 什么是正则表达式?
正则表达式(Regex)是一种描述字符串模式的强大语法,可用于:
- 🔍 验证输入:如邮箱、手机号、身份证号
- 🧩 提取信息:从网页、日志中抓取关键数据
- ✏️ 替换内容:批量修改文本
- ✂️ 分割字符串:按复杂规则拆分文本
2. 基本语法与元字符
|-----------|-----------------------------|----------------------------------------|
| 元字符 | 说明 | 示例 |
| .
| 匹配任意单个字符(除换行符) | a.c
→ "abc", "a2c" |
| ^
| 匹配字符串开头 | ^Hello
→ "Hello World" ✅,"Hi Hello" ❌ |
| $
| 匹配字符串结尾 | world$
→ "Hello world" ✅ |
| *
| 前面字符出现 0 次或多次 | ab*c
→ "ac", "abc", "abbc" |
| +
| 前面字符出现 1 次或多次 | ab+c
→ "abc", "abbc" ✅,"ac" ❌ |
| ?
| 前面字符出现 0 次或 1 次 | colou?r
→ "color", "colour" |
| \d
| 匹配数字(等价于 [0-9]
) | \d{3}
→ "123" |
| \w
| 匹配字母、数字、下划线([a-zA-Z0-9_]
) | \w+
→ "user_123" |
| \s
| 匹配空白字符(空格、制表符、换行) | a\sb
→ "a b" |
| [...]
| 匹配括号内任意一个字符 | [aeiou]
→ 匹配任一元音字母 |
| ( ... )
| 分组,用于捕获子表达式 | (\d{4})-(\d{2})
|
3. 使用 re
模块
3.1 导入模块
import re
3.2 常用函数详解
re.match()
:从字符串开头匹配
result = re.match(r'\d+', '123abc')
if result:
print(result.group()) # 输出:123
⚠️ 注意 :match()
只检查开头,re.match(r'\d+', 'abc123')
返回 None
。
re.search()
:在整个字符串中搜索第一个匹配项
result = re.search(r'\d+', 'abc123def')
if result:
print(result.group()) # 输出:123
✅ 更常用,不局限于开头。
re.findall()
:返回所有匹配结果的列表
matches = re.findall(r'\d+', 'abc123def456ghi')
print(matches) # 输出:['123', '456']
✅ 简单直接,适合提取多个值。
re.finditer()
:返回匹配对象的迭代器(内存友好)
for match in re.finditer(r'\d+', 'abc123def456ghi'):
print(f"找到数字:{match.group()},位置:{match.span()}")
# 输出:
# 找到数字:123,位置:(3, 6)
# 找到数字:456,位置:(7, 10)
✅ 适合大文本处理,避免一次性加载所有结果。
re.sub()
:替换匹配的内容
new_text = re.sub(r'\d+', 'NUM', 'abc123def456')
print(new_text) # 输出:abcNUMdefNUM
# 支持函数替换
def double_num(match):
num = int(match.group())
return str(num * 2)
result = re.sub(r'\d+', double_num, '价格:100元和200元')
print(result) # 输出:价格:200元和400元
re.split()
:使用正则表达式分割字符串
parts = re.split(r'\s+', 'apple banana cherry')
print(parts) # 输出:['apple', 'banana', 'cherry']
# 保留分隔符
parts_with_sep = re.split(r'(\s+)', 'apple banana')
print(parts_with_sep) # ['apple', ' ', 'banana']
4. 实际应用示例
✅ 验证邮箱格式
def is_valid_email(email):
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return re.match(pattern, email) is not None
print(is_valid_email("user@example.com")) # True
print(is_valid_email("invalid.email")) # False
🔍 模式解析:
^
:开头[a-zA-Z0-9._%+-]+
:用户名(字母、数字、._%+-)@
:@ 符号[a-zA-Z0-9.-]+
:域名\.
:点号(转义)[a-zA-Z]{2,}
:顶级域名(至少2字母)$
:结尾
✅ 提取网页中的 URL
text = "访问我们的网站 https://www.example.com 或 http://blog.example.org"
urls = re.findall(r'https?://[^\s]+', text)
print(urls)
# 输出:['https://www.example.com', 'http://blog.example.org']
🔍 模式解析:
https?
:匹配 http 或 https://
:协议分隔符[^\s]+
:非空白字符(直到空格或换行)
三、JSON(JavaScript Object Notation)
1. 什么是 JSON?
JSON 是一种轻量级的数据交换格式,基于文本,具有以下优点:
- 👁️ 人类可读
- 🤖 机器易解析
- 🌐 跨语言支持(Python、JavaScript、Java 等)
2. JSON 支持的数据类型
|-----------------------|------------------|
| JSON 类型 | 对应 Python 类型 |
| 字符串 "hello"
| str
|
| 数字 42
, 3.14
| int
, float
|
| 布尔值 true
, false
| True
, False
|
| null
| None
|
| 对象 {"key": "value"}
| dict
|
| 数组 ["a", "b"]
| list
|
3. JSON 示例
{
"name": "Alice",
"age": 25,
"is_student": false,
"courses": ["数学", "英语"],
"address": {
"city": "北京",
"zipcode": "100000"
}
}
4. 使用 json
模块
4.1 导入模块
import json
4.2 序列化:Python 对象 → JSON 字符串(json.dumps()
)
data = {
"name": "Bob",
"age": 30,
"hobbies": ["reading", "swimming"]
}
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)
输出:
{
"name": "Bob",
"age": 30,
"hobbies": [
"reading",
"swimming"
]
}
✅ 参数说明:
ensure_ascii=False
:允许输出中文(否则会转义)indent=2
:美化输出,2 空格缩进
4.3 反序列化:JSON 字符串 → Python 对象(json.loads()
)
json_str = '{"name": "Charlie", "score": 95.5}'
data = json.loads(json_str)
print(data["name"]) # Charlie
print(data["score"]) # 95.5(float 类型)
4.4 读写 JSON 文件
写入文件
with open("data.json", "w", encoding="utf-8") as file:
json.dump(data, file, ensure_ascii=False, indent=2)
✅ json.dump()
直接写入文件,无需先转字符串。
读取文件
with open("data.json", "r", encoding="utf-8") as file:
loaded_data = json.load(file)
print(loaded_data)
✅ json.load()
直接从文件读取并解析。
5. 实际应用示例:模拟 API 响应处理
import json
# 模拟从 Web API 获取的 JSON 响应
api_response = '''
{
"users": [
{"id": 1, "name": "Alice", "email": "alice@example.com"},
{"id": 2, "name": "Bob", "email": "bob@example.com"}
],
"total": 2
}
'''
# 解析 JSON
response_data = json.loads(api_response)
# 提取用户信息
for user in response_data["users"]:
print(f"用户: {user['name']}, 邮箱: {user['email']}")
输出:
用户: Alice, 邮箱: alice@example.com
用户: Bob, 邮箱: bob@example.com
四、综合示例:日志分析器
结合正则表达式和 JSON,编写一个结构化日志分析器。
import re
import json
# 模拟日志行
log_line = '2025-08-04 10:30:15 ERROR User login failed for user=admin from IP=192.168.1.100'
# 使用正则提取信息
pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) (\w+) (.+) from IP=(\d+\.\d+\.\d+\.\d+)'
match = re.match(pattern, log_line)
if match:
timestamp, level, message, ip = match.groups()
# 构建结构化数据
log_entry = {
"timestamp": timestamp,
"level": level,
"message": message,
"ip": ip
}
# 转换为 JSON 字符串
json_log = json.dumps(log_entry, ensure_ascii=False, indent=2)
print(json_log)
输出:
{
"timestamp": "2025-08-04 10:30:15",
"level": "ERROR",
"message": "User login failed for user=admin",
"ip": "192.168.1.100"
}
✅ 应用场景:日志收集、安全审计、系统监控。
五、总结:正则表达式与 JSON 的核心要点
|-----------|--------------|----------|------------------|
| 技术 | 核心用途 | 关键模块 | 推荐使用场景 |
| 正则表达式 | 文本模式匹配、提取、替换 | re
| 验证输入、日志分析、爬虫数据提取 |
| JSON | 数据序列化与反序列化 | json
| API 通信、配置文件、数据存储 |
六、最佳实践与建议
|-------------|--------------------------------------------|
| 建议 | 说明 |
| ✅ 正则表达式 | 使用 r''
原始字符串避免转义问题 |
| ✅ 调试正则 | 使用 regex101.com 在线测试 |
| ✅ 处理异常 | json.loads()
可能抛出 json.JSONDecodeError
|
| ✅ 编码处理 | 读写 JSON 文件时指定 encoding="utf-8"
|
| ✅ 性能优化 | 复用正则模式:pattern = re.compile(r'\d+')
|
七、动手练习
1. 验证手机号(如 13812345678)
def is_valid_phone(phone):
# 中国大陆手机号:1 开头,第二位 3-9,共 11 位
pattern = r'^1[3-9]\d{9}$'
return re.match(pattern, phone) is not None
print(is_valid_phone("13812345678")) # True
print(is_valid_phone("12345678901")) # False
2. 保存个人信息为 JSON 文件
import json
profile = {
"name": "张三",
"age": 28,
"city": "上海",
"skills": ["Python", "数据分析", "Web 开发"]
}
with open("profile.json", "w", encoding="utf-8") as file:
json.dump(profile, file, ensure_ascii=False, indent=2)
print("个人信息已保存到 profile.json")
3. 分析日志文件并输出 JSON
假设 logs.txt
内容:
2025-08-04 10:00:00 INFO System started
2025-08-04 10:01:23 ERROR Database connection failed
2025-08-04 10:02:45 WARNING Disk usage high
import re
import json
pattern = r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) (\w+) (.+)'
error_logs = []
with open("logs.txt", "r", encoding="utf-8") as file:
for line in file:
match = re.match(pattern, line.strip())
if match:
timestamp, level, message = match.groups()
if level == "ERROR":
error_logs.append({
"timestamp": timestamp,
"level": level,
"message": message
})
# 输出为 JSON
json_output = json.dumps(error_logs, ensure_ascii=False, indent=2)
print(json_output)
🚀 学习建议
- 多练习正则:从简单模式开始,逐步构建复杂表达式。
- 理解 JSON 结构:熟悉嵌套对象与数组的处理。
- 结合使用:在真实项目中,常需用正则清洗原始数据,再组织成 JSON。
- 进阶学习:
-
- 正则的贪婪 vs 非贪婪 模式(
*?
,+?
) json
模块的cls
参数(自定义编码器)- 使用
pathlib
和json
构建配置管理器
- 正则的贪婪 vs 非贪婪 模式(