19.1 正则表达式概念
正则表达式(Regular Expression)是用于匹配字符串模式的强大工具。
应用场景
- 数据验证(邮箱、电话、密码强度)
- 文本提取
- 搜索与替换
- 日志分析
19.2 基本语法
字符匹配
| 模式 |
说明 |
示例 |
. |
任意字符(除换行) |
a.c 匹配 “abc” |
\d |
数字 |
\d\d 匹配 “12” |
\w |
字母数字下划线 |
\w+ 匹配 “hello” |
\s |
空白字符 |
a\s b 匹配 “a b” |
^ |
开头 |
^Hello |
$ |
结尾 |
World$ |
示例
1 2 3 4 5 6 7 8 9 10 11 12
| import re
text = "Hello 123 World 456"
print(re.findall(r"\d+", text))
print(re.findall(r"\w+", text))
print(re.findall(r"\s+", text))
|
19.3 字符类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import re
print(re.findall(r"[aeiou]", "hello world"))
print(re.findall(r"[a-z]", "Hello 123")) print(re.findall(r"[0-9]", "Hello 123"))
print(re.findall(r"[^0-9]", "Hello 123"))
print(re.findall(r"[a-zA-Z0-9]", "Hello! 123"))
|
19.4 量词
| 量词 |
说明 |
示例 |
* |
0 次或多次 |
ab*c 匹配 “ac”, “abc”, “abbc” |
+ |
1 次或多次 |
ab+c 匹配 “abc”, “abbc” |
? |
0 次或 1 次 |
ab?c 匹配 “ac”, “abc” |
{n} |
恰好 n 次 |
a{3} 匹配 “aaa” |
{n,} |
至少 n 次 |
a{2,} 匹配 “aa”, “aaa” |
{n,m} |
n 到 m 次 |
a{2,4} 匹配 “aa”, “aaa”, “aaaa” |
示例
1 2 3 4 5 6 7
| import re
text = "a ab abb abbb abbbb"
print(re.findall(r"ab*", text)) print(re.findall(r"ab+", text)) print(re.findall(r"ab{2,3}", text))
|
19.5 分组与捕获
基本分组
1 2 3 4 5 6 7 8 9 10 11
| import re
text = "2024-11-30"
match = re.search(r"(\d{4})-(\d{2})-(\d{2})", text) if match: print(f"年: {match.group(1)}") print(f"月: {match.group(2)}") print(f"日: {match.group(3)}") print(f"全部: {match.group(0)}")
|
命名分组
1 2 3 4 5 6 7 8 9
| import re
text = "2024-11-30" match = re.search(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})", text)
if match: print(match.group("year")) print(match.group("month")) print(match.group("day"))
|
非捕获分组
1 2 3 4 5 6 7
| import re
print(re.findall(r"(abc)+", "abcabc"))
print(re.findall(r"(?:abc)+", "abcabc"))
|
19.6 re 模块常用函数
match() - 从开头匹配
1 2 3 4 5 6 7 8
| import re
text = "Hello World" match = re.match(r"Hello", text) print(match.group())
match = re.match(r"World", text) print(match)
|
search() - 搜索任意位置
1 2 3 4 5
| import re
text = "Hello World" match = re.search(r"World", text) print(match.group())
|
findall() - 查找所有匹配
1 2 3 4 5 6 7 8
| import re
text = "Phone: 123-456-7890, Email: test@example.com" phones = re.findall(r"\d{3}-\d{3}-\d{4}", text) print(phones)
emails = re.findall(r"\w+@\w+\.\w+", text) print(emails)
|
sub() - 替换
1 2 3 4 5 6 7 8 9
| import re
text = "Hello 123 World 456" result = re.sub(r"\d+", "XXX", text) print(result)
result = re.sub(r"\d+", "XXX", text, count=1) print(result)
|
split() - 分割
1 2 3 4 5
| import re
text = "one,two;three four" result = re.split(r"[,;\s]+", text) print(result)
|
19.7 编译正则表达式
1 2 3 4 5 6 7 8 9 10
| import re
pattern = re.compile(r"\d{3}-\d{3}-\d{4}")
text1 = "Phone: 123-456-7890" text2 = "Phone: 987-654-3210"
print(pattern.findall(text1)) print(pattern.findall(text2))
|
19.8 实用示例
邮箱验证
1 2 3 4 5 6 7 8 9
| import re
def validate_email(email): pattern = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$" return bool(re.match(pattern, email))
print(validate_email("test@example.com")) print(validate_email("invalid@email")) print(validate_email("user.name@domain.org"))
|
密码强度检查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import re
def check_password(password): if len(password) < 8: return False if not re.search(r"[A-Z]", password): return False if not re.search(r"[a-z]", password): return False if not re.search(r"\d", password): return False if not re.search(r"[!@#$%^&*]", password): return False return True
print(check_password("Abc123!@")) print(check_password("weak"))
|
提取 URL
1 2 3 4 5
| import re
text = "Visit https://www.example.com or http://test.org" urls = re.findall(r"https?://\S+", text) print(urls)
|
19.9 本章小结
- 正则表达式用于模式匹配和文本处理
- 常用模式:
\d、\w、\s、.、^、$
- 量词:
*、+、?、{n,m}
- 分组:
() 捕获,(?:) 非捕获,(?P<name>) 命名
- re 模块:
match()、search()、findall()、sub()、split()
- 预编译提高重复使用效率
练习题
- 编写正则表达式匹配中国大陆手机号(11 位,1 开头)
- 从 HTML 中提取所有
<a> 标签的 href 属性
- 验证日期格式 YYYY-MM-DD
- 以下代码输出什么?
1 2
| import re print(re.findall(r"\d+", "a1b2c3"))
|