Python3 正则表达式:文本处理的魔法工具
内容简介
本系列文章是为 Python3 学习者精心设计的一套全面、实用的学习指南,旨在帮助读者从基础入门到项目实战,全面提升编程能力。文章结构由 5 个版块组成,内容层层递进,逻辑清晰。
- 基础速通:n 个浓缩提炼的核心知识点,夯实编程基础;
- 经典范例:10 个贴近实际的应用场景,深入理解 Python3 的编程技巧和应用方法;
- 避坑宝典:10 个典型错误解析,提供解决方案,帮助读者避免常见的编程陷阱;
- 水平考试:10 道测试题目,检验学习成果,附有标准答案,以便自我评估;
- 实战案例:3 个迷你项目开发,带领读者从需求分析到代码实现,掌握项目开发的完整流程。
无论你是 Python3 初学者,还是希望提升实战能力的开发者,本系列文章都能为你提供清晰的学习路径和实用的编程技巧,助你快速成长为 Python3 编程高手。
阅读建议
- 初学者:建议从 “基础速通” 开始,系统学习 Python3 的基础知识,然后通过 “经典范例” 和 “避坑宝典” 加深理解,最后通过 “水平考试” 和 “实战案例” 巩固所学内容;
- 有经验的开发者:可以直接跳转到 “经典范例” 和 “避坑宝典”,快速掌握 Python3 的高级应用技巧和常见错误处理方法,然后通过 “实战案例” 提升项目开发能力;
- 选择性学习:如果读者对某个特定主题感兴趣,可以直接选择相应版块学习。各版块内容既相互独立又逻辑关联,方便读者根据自身需求灵活选择;
- 测试与巩固:完成每个版块的学习后,建议通过 “水平考试” 检验学习效果,并通过 “实战案例” 将理论知识转化为实际技能;
- 项目实战优先:如果你更倾向于实战学习,可以直接从 “实战案例” 入手,边做边学,遇到问题再回溯相关知识点。
一、基础速通
正则表达式(Regular Expression,简称 regex 或 regexp)是一种强大的工具,用于匹配和处理文本。Python 通过 re
模块提供了对正则表达式的支持。正则表达式可以用于搜索、替换、分割和验证字符串。
1. 基本概念
- 模式(Pattern):正则表达式的核心是模式,它定义了你要匹配的文本规则。
- 元字符(Metacharacters):在正则表达式中具有特殊意义的字符,如
.
,*
,+
,?
,^
,$
,\
,|
,{
,}
,[
,]
,(
,)
等。 - 普通字符:除了元字符之外的字符,如字母、数字等。
2. 常用元字符
.
:匹配除换行符以外的任意单个字符。^
:匹配字符串的开头。$
:匹配字符串的结尾。*
:匹配前面的字符零次或多次。+
:匹配前面的字符一次或多次。?
:匹配前面的字符零次或一次。{n}
:匹配前面的字符恰好 n 次。{n,}
:匹配前面的字符至少 n 次。{n,m}
:匹配前面的字符至少 n 次,至多 m 次。\
:转义字符,用于匹配元字符本身。|
:或操作符,匹配左边或右边的表达式。[]
:字符集,匹配其中的任意一个字符。()
:分组,将多个字符作为一个整体进行匹配。
3. 常用字符集
\d
:匹配任意数字,等价于[0-9]
。\D
:匹配任意非数字字符,等价于[^0-9]
。\w
:匹配任意字母、数字或下划线,等价于[a-zA-Z0-9_]
。\W
:匹配任意非字母、数字或下划线的字符,等价于[^a-zA-Z0-9_]
。\s
:匹配任意空白字符,包括空格、制表符、换行符等。\S
:匹配任意非空白字符。
4. re
模块常用函数
re.match(pattern, string)
:从字符串的起始位置匹配正则表达式,如果匹配成功返回匹配对象,否则返回None
。re.search(pattern, string)
:在字符串中搜索匹配正则表达式的第一个位置,如果匹配成功返回匹配对象,否则返回None
。re.findall(pattern, string)
:返回字符串中所有匹配正则表达式的子串,返回一个列表。re.finditer(pattern, string)
:返回一个迭代器,包含所有匹配正则表达式的子串。re.sub(pattern, repl, string)
:将字符串中匹配正则表达式的部分替换为repl
。re.split(pattern, string)
:根据正则表达式匹配的子串将字符串分割,返回一个列表。
5. 示例
5.1 匹配数字
import retext = "The price is 123.45 dollars."
pattern = r'\d+\.\d+'
match = re.search(pattern, text)
if match:print("Found:", match.group())
5.2 替换字符串
import retext = "Hello, world!"
pattern = r'world'
repl = 'Python'
new_text = re.sub(pattern, repl, text)
print(new_text) # 输出: Hello, Python!
5.3 分割字符串
import retext = "apple,banana,cherry"
pattern = r','
result = re.split(pattern, text)
print(result) # 输出: ['apple', 'banana', 'cherry']
5.4 查找所有匹配
import retext = "The rain in Spain falls mainly in the plain."
pattern = r'\bin\b'
matches = re.findall(pattern, text)
print(matches) # 输出: ['in', 'in', 'in']
6. 分组和捕获
分组使用 ()
来定义,可以捕获匹配的子串。
import retext = "John Doe, Jane Doe"
pattern = r'(\w+) (\w+)'
matches = re.findall(pattern, text)
for first_name, last_name in matches:print(f"First: {first_name}, Last: {last_name}")
7. 非贪婪匹配
默认情况下,*
和 +
是贪婪的,会尽可能多地匹配字符。可以在它们后面加上 ?
来使其变为非贪婪匹配。
import retext = "<html><head><title>Title</title></head></html>"
pattern = r'<.*?>'
matches = re.findall(pattern, text)
print(matches) # 输出: ['<html>', '<head>', '<title>', '</title>', '</head>', '</html>']
8. 编译正则表达式
如果需要多次使用同一个正则表达式,可以将其编译为正则表达式对象,以提高效率。
import repattern = re.compile(r'\d+')
text = "There are 3 apples and 5 oranges."
matches = pattern.findall(text)
print(matches) # 输出: ['3', '5']
9. 标志(Flags)
re
模块提供了一些标志来修改正则表达式的行为,如忽略大小写、多行匹配等。
re.IGNORECASE
或re.I
:忽略大小写。re.MULTILINE
或re.M
:多行模式,^
和$
匹配每行的开头和结尾。re.DOTALL
或re.S
:使.
匹配包括换行符在内的所有字符。
import retext = "Hello\nWorld"
pattern = r'^world'
match = re.search(pattern, text, re.IGNORECASE | re.MULTILINE)
if match:print("Found:", match.group())
小结
正则表达式是处理文本的强大工具,Python 的 re
模块提供了丰富的功能来支持正则表达式的使用。通过掌握正则表达式的基本语法和 re
模块的常用函数,你可以高效地处理各种文本匹配和替换任务。
二、经典范例
以下是 10 个经典的正则表达式应用实例,每个实例都包含正则表达式的解释、测试代码以及执行结果的注释说明。
1. 匹配邮箱地址
正则表达式: r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
- 解释:匹配常见的邮箱地址格式。
^
和$
表示字符串的开始和结束。[a-zA-Z0-9_.+-]+
匹配用户名部分。@
匹配邮箱中的@
符号。[a-zA-Z0-9-]+
匹配域名部分。\.
匹配域名中的点.
。[a-zA-Z0-9-.]+
匹配顶级域名部分。
import repattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
emails = ["test@example.com", "user.name+tag+sorting@example.com", "invalid-email@com"]
for email in emails:if re.match(pattern, email):print(f"Valid: {email}")else:print(f"Invalid: {email}")# 执行结果:
# Valid: test@example.com
# Valid: user.name+tag+sorting@example.com
# Invalid: invalid-email@com
2. 匹配手机号码
正则表达式: r'^1[3-9]\d{9}$'
- 解释:匹配中国大陆的手机号码。
1
表示手机号码的第一位。[3-9]
表示第二位可以是 3 到 9 之间的数字。\d{9}
表示后面跟着 9 位数字。
import repattern = r'^1[3-9]\d{9}$'
phones = ["13800138000", "12345678901", "19912345678"]
for phone in phones:if re.match(pattern, phone):print(f"Valid: {phone}")else:print(f"Invalid: {phone}")# 执行结果:
# Valid: 13800138000
# Invalid: 12345678901
# Valid: 19912345678
3. 匹配 URL
正则表达式: r'https?://(?:www\.)?\S+'
- 解释:匹配 HTTP 或 HTTPS 协议的 URL。
https?
匹配http
或https
。://
匹配 URL 中的协议分隔符。(?:www\.)?
匹配可选的www.
。\S+
匹配 URL 的其余部分。
import repattern = r'https?://(?:www\.)?\S+'
urls = ["https://www.example.com", "http://example.com", "ftp://example.com"]
for url in urls:if re.match(pattern, url):print(f"Valid: {url}")else:print(f"Invalid: {url}")# 执行结果:
# Valid: https://www.example.com
# Valid: http://example.com
# Invalid: ftp://example.com
4. 匹配日期(YYYY-MM-DD)
正则表达式: r'^\d{4}-[01]?[0-2]-[0123]?[0-9]$'
- 解释:匹配
YYYY-MM-DD
格式的日期。 \d{4}
匹配 4 位年份。-
匹配日期分隔符。[01]?[0-2]
匹配 2 位月份。[0123]?[0-9]
匹配 2 位日期。
import repattern = r'^\d{4}-[01]?[0-2]-[0123]?[0-9]$'
dates = ["2023-10-05", "2023/10/05", "2023-13-01"]
for date in dates:if re.match(pattern, date):print(f"Valid: {date}")else:print(f"Invalid: {date}")# 执行结果:
# Valid: 2023-10-05
# Invalid: 2023/10/05
# Invalid: 2023-13-01
5. 匹配 IP 地址
正则表达式: r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'
- 解释:匹配 IPv4 地址。
\d{1,3}
匹配 1 到 3 位数字。\.
匹配 IP 地址中的点.
。
import repattern = r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'
ips = ["192.168.1.1", "256.256.256,256", "127.0.0.1"]
for ip in ips:if re.match(pattern, ip):print(f"Valid: {ip}")else:print(f"Invalid: {ip}")# 执行结果:
# Valid: 192.168.1.1
# Invalid: 256.256.256.256
# Valid: 127.0.0.1
6. 匹配 HTML 标签
正则表达式: r'<(\w+)[^>]*>(.*?)</\1>'
- 解释:匹配 HTML 标签及其内容。
<(\w+)
匹配标签名。[^>]*
匹配标签内的属性。>(.*?)
匹配标签内容。</\1>
匹配对应的闭合标签。
import repattern = r'<(\w+)[^>]*>(.*?)</\1>'
html = "<div class='test'>Hello World</div>"
match = re.search(pattern, html)
if match:print(f"Tag: {match.group(1)}, Content: {match.group(2)}")# 执行结果:
# Tag: div, Content: Hello World
7. 匹配中文字符
正则表达式: r'[\u4e00-\u9fff]+'
- 解释:匹配中文字符。
[\u4e00-\u9fff]
是中文字符的 Unicode 范围。
import repattern = r'[\u4e00-\u9fff]+'
text = "Hello 世界"
matches = re.findall(pattern, text)
print(matches) # 执行结果: ['世界']
8. 匹配密码强度
正则表达式: r'^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[\W_]).{8,}$'
- 解释:匹配强密码(至少 8 位,包含大小写字母、数字和特殊字符)。
(?=.*[A-Z])
确保至少有一个大写字母。(?=.*[a-z])
确保至少有一个小写字母。(?=.*\d)
确保至少有一个数字。(?=.*[\W_])
确保至少有一个特殊字符。.{8,}
确保密码长度至少为 8。
import repattern = r'^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[\W_]).{8,}$'
passwords = ["Password123!", "weakpass", "StrongPass1"]
for pwd in passwords:if re.match(pattern, pwd):print(f"Strong: {pwd}")else:print(f"Weak: {pwd}")# 执行结果:
# Strong: Password123!
# Weak: weakpass
# Strong: StrongPass1
9. 匹配十六进制颜色值
正则表达式: r'^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$'
- 解释:匹配十六进制颜色值(如
#FFFFFF
或#FFF
)。 #
匹配颜色值开头的#
。[A-Fa-f0-9]{6}
匹配 6 位十六进制值。[A-Fa-f0-9]{3}
匹配 3 位十六进制值。
import repattern = r'^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$'
colors = ["#FFFFFF", "#FFF", "#123456", "#GHIJKL"]
for color in colors:if re.match(pattern, color):print(f"Valid: {color}")else:print(f"Invalid: {color}")# 执行结果:
# Valid: #FFFFFF
# Valid: #FFF
# Valid: #123456
# Invalid: #GHIJKL
10. 匹配文件名和扩展名
正则表达式: r'^(\w+)\.(\w+)$'
- 解释:匹配文件名和扩展名。
(\w+)
匹配文件名。\.
匹配点.
。(\w+)
匹配扩展名。
import repattern = r'^(\w+)\.(\w+)$'
filename = "example.txt"
match = re.match(pattern, filename)
if match:print(f"Filename: {match.group(1)}, Extension: {match.group(2)}")# 执行结果:
# Filename: example, Extension: txt
三、避坑宝典
在使用正则表达式时,初学者和中级用户经常会遇到一些常见错误。以下是 10 种常见的正则表达式错误、原因分析以及纠错方法。
1. 忘记转义特殊字符
错误:直接使用 .
、*
、+
等元字符而未转义。
import re
pattern = r'example.com'
text = "example-com"
match = re.search(pattern, text) # 无法匹配
原因:.
是元字符,匹配任意字符,而不是字面的点 .
。
纠错:使用 \.
转义。
pattern = r'example\.com'
2. 贪婪匹配导致意外结果
错误:使用 .*
或 .+
时匹配过多内容。
import re
pattern = r'<.*>'
text = "<div>Hello</div><p>World</p>"
match = re.search(pattern, text) # 匹配整个字符串
原因:*
和 +
是贪婪的,会尽可能多地匹配字符。
纠错:使用非贪婪匹配 .*?
或 .+?
。
pattern = r'<.*?>'
3. 忽略多行模式
错误:在多行文本中使用 ^
或 $
时,未启用多行模式。
import re
pattern = r'^Hello'
text = "Line1\nHello\nLine2"
match = re.search(pattern, text) # 无法匹配
原因:默认情况下,^
和 $
只匹配字符串的开头和结尾。
纠错:使用 re.MULTILINE
标志。
match = re.search(pattern, text, re.MULTILINE)
4. 字符集未正确使用
错误:在字符集中未正确使用 -
。
import re
pattern = r'[A-Z]'
text = "abc123"
match = re.search(pattern, text) # 无法匹配小写字母
原因:[A-Z]
只匹配大写字母。
纠错:使用 [A-Za-z]
匹配所有字母。
pattern = r'[A-Za-z]'
5. 分组捕获错误
错误:未正确使用分组捕获。
import re
pattern = r'(\d{2})-(\d{2})-(\d{4})'
text = "12-31-2023"
match = re.search(pattern, text)
if match:print(match.group(1)) # 输出 12
原因:分组索引从 1 开始,group(0)
是整个匹配内容。
纠错:确保使用正确的分组索引。
if match:print(match.group(1), match.group(2), match.group(3)) # 输出 12 31 2023
6. 忽略大小写
错误:未忽略大小写导致匹配失败。
import re
pattern = r'hello'
text = "Hello World"
match = re.search(pattern, text) # 无法匹配
原因:默认情况下,正则表达式区分大小写。
纠错:使用 re.IGNORECASE
标志。
match = re.search(pattern, text, re.IGNORECASE)
7. 量词使用错误
错误:量词使用不当导致匹配失败。
import re
pattern = r'\d{3,5}'
text = "123"
match = re.search(pattern, text) # 匹配成功,但可能不符合预期
原因:{3,5}
表示匹配 3 到 5 个数字,但可能匹配过多。
纠错:根据需求调整量词。
pattern = r'\d{3}' # 只匹配 3 个数字
8. 未正确处理边界
错误:未使用单词边界 \b
。
import re
pattern = r'cat'
text = "category"
match = re.search(pattern, text) # 匹配成功,但可能不符合预期
原因:cat
会匹配 category
中的 cat
。
纠错:使用 \b
确保匹配完整单词。
pattern = r'\bcat\b'
9. 忽略空白字符
错误:未正确处理空白字符。
import re
pattern = r'hello world'
text = "hello world"
match = re.search(pattern, text) # 无法匹配
原因:正则表达式中的空格是字面匹配。
纠错:使用 \s+
匹配空白字符。
pattern = r'hello\s+world'
10. 未正确处理换行符
错误:未正确处理多行文本中的换行符。
import re
pattern = r'^Hello'
text = "Line1\nHello\nLine2"
match = re.search(pattern, text) # 无法匹配
原因:不能正确处理换行符。
纠错:使用 re.MULTILINE
标志。
match = re.search(pattern, text, re.MULTILINE)
小结
正则表达式虽然强大,但在使用时容易犯一些常见错误。通过理解这些错误的原因并掌握纠错方法,可以更高效地使用正则表达式处理文本。
四、水平考试
这是一份关于“正则表达式”的测试试卷。包含:选择题:15 道、填空题:10 道和 编程题:5 道,总分 100 分。每道题后附有答案和解析。
选择题(每题 2 分,共 30 分)
-
以下哪个正则表达式可以匹配任意数字?
- A.
\d
- B.
\D
- C.
\w
- D.
\s
答案:A
解析:\d
匹配任意数字,\D
匹配非数字,\w
匹配字母、数字或下划线,\s
匹配空白字符。
- A.
-
以下哪个正则表达式可以匹配一个或多个字母?
- A.
[a-z]
- B.
[a-z]+
- C.
[a-z]*
- D.
[a-z]?
答案:B
解析:+
表示前面的字符至少出现一次。
- A.
-
以下哪个正则表达式可以匹配字符串的开头?
- A.
$
- B.
^
- C.
\b
- D.
\B
答案:B
解析:^
匹配字符串的开头,$
匹配字符串的结尾。
- A.
-
以下哪个正则表达式可以匹配一个单词边界?
- A.
\b
- B.
\B
- C.
^
- D.
$
答案:A
解析:\b
匹配单词边界,\B
匹配非单词边界。
- A.
-
以下哪个正则表达式可以匹配一个浮点数?
- A.
\d+\.\d+
- B.
\d*\.\d*
- C.
\d+\.\d*
- D.
\d*\.\d+
答案:A
解析:\d+\.\d+
匹配至少一个数字,后跟一个小数点,再跟至少一个数字。
- A.
-
以下哪个正则表达式可以匹配一个邮箱地址?
- A.
[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z]+
- B.
[a-zA-Z0-9]+@[a-zA-Z0-9]+
- C.
[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z0-9]+
- D.
[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z0-9]+\.
答案:A
解析:邮箱地址的格式为用户名@域名.顶级域名
。
- A.
-
以下哪个正则表达式可以匹配一个 URL?
- A.
https?://\S+
- B.
http://\S+
- C.
https://\S+
- D.
http://\S
答案:A
解析:https?
匹配http
或https
,\S+
匹配非空白字符。
- A.
-
以下哪个正则表达式可以匹配一个 HTML 标签?
- A.
<.*>
- B.
<.*?>
- C.
<.+>
- D.
<.+?>
答案:B
解析:<.*?>
使用非贪婪匹配,避免匹配过多内容。
- A.
-
以下哪个正则表达式可以匹配一个中文字符?
- A.
[\u4e00-\u9fff]
- B.
[a-zA-Z]
- C.
\d
- D.
\w
答案:A
解析:[\u4e00-\u9fff]
是中文字符的 Unicode 范围。
- A.
-
以下哪个正则表达式可以匹配一个 IP 地址?
- A.
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
- B.
\d{1,3}\.\d{1,3}\.\d{1,3}
- C.
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
- D.
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
答案:A
解析:IPv4 地址由 4 个 1 到 3 位的数字组成,用.
分隔。
- A.
-
以下哪个正则表达式可以匹配一个日期(YYYY-MM-DD)?
- A.
\d{4}-\d{2}-\d{2}
- B.
\d{2}-\d{2}-\d{4}
- C.
\d{4}/\d{2}/\d{2}
- D.
\d{2}/\d{2}/\d{4}
答案:A
解析:\d{4}-\d{2}-\d{2}
匹配YYYY-MM-DD
格式的日期。
- A.
-
以下哪个正则表达式可以匹配一个时间(HH:MM:SS)?
- A.
\d{2}:\d{2}:\d{2}
- B.
\d{2}:\d{2}
- C.
\d{2}:\d{2}:\d{2}:\d{2}
- D.
\d{2}:\d{2}:\d{2}:\d{2}:\d{2}
答案:A
解析:\d{2}:\d{2}:\d{2}
匹配HH:MM:SS
格式的时间。
- A.
-
以下哪个正则表达式可以匹配一个十六进制颜色值?
- A.
#[A-Fa-f0-9]{6}
- B.
#[A-Fa-f0-9]{3}
- C.
#[A-Fa-f0-9]{6}|#[A-Fa-f0-9]{3}
- D.
#[A-Fa-f0-9]{6}|#[A-Fa-f0-9]{3}|#[A-Fa-f0-9]{2}
答案:C
解析:十六进制颜色值可以是 3 位或 6 位。
- A.
-
以下哪个正则表达式可以匹配一个文件名和扩展名?
- A.
\w+\.\w+
- B.
\w+\.\w
- C.
\w+\.\w{2,4}
- D.
\w+\.\w+\.\w+
答案:A
解析:\w+\.\w+
匹配文件名和扩展名。
- A.
-
以下哪个正则表达式可以匹配一个强密码(至少 8 位,包含大小写字母、数字和特殊字符)?
- A.
^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[\W_]).{8,}$
- B.
^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{8,}$
- C.
^(?=.*[A-Z])(?=.*[a-z]).{8,}$
- D.
^(?=.*[A-Z])(?=.*\d).{8,}$
答案:A
解析:(?=.*[A-Z])
确保至少有一个大写字母,(?=.*[a-z])
确保至少有一个小写字母,(?=.*\d)
确保至少有一个数字,(?=.*[\W_])
确保至少有一个特殊字符。
- A.
填空题(每题 3 分,共 30 分)
-
正则表达式
\d{3}-\d{2}-\d{4}
可以匹配的格式是:________。
答案:XXX-XX-XXXX
(例如:123-45-6789) -
正则表达式
^[A-Za-z]+$
可以匹配的字符串是:________。
答案:仅包含字母的字符串 -
正则表达式
\b\w+\b
可以匹配的字符串是:________。
答案:一个完整的单词 -
正则表达式
\d{2}:\d{2}:\d{2}
可以匹配的格式是:________。
答案:HH:MM:SS
(例如:12:34:56) -
正则表达式
[\u4e00-\u9fff]+
可以匹配的字符串是:________。
答案:中文字符 -
正则表达式
^[a-zA-Z0-9_]{4,16}$
可以匹配的字符串是:________。
答案:4 到 16 位的用户名(字母、数字、下划线) -
正则表达式
https?://\S+
可以匹配的字符串是:________。
答案:HTTP 或 HTTPS 协议的 URL -
正则表达式
\d+\.\d+
可以匹配的字符串是:________。
答案:浮点数(例如:3.14) -
正则表达式
^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$
可以匹配的字符串是:________。
答案:十六进制颜色值(例如:#FFFFFF 或 #FFF) -
正则表达式
^(\d{4})-(\d{2})-(\d{2})$
可以匹配的格式是:________。
答案:YYYY-MM-DD
(例如:2023-10-05)
编程题(每题 8 分,共 40 分)
-
编写一个正则表达式,匹配一个合法的邮箱地址。
答案:import re pattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$' emails = ["test@example.com", "invalid-email@com"] for email in emails:if re.match(pattern, email):print(f"Valid: {email}")else:print(f"Invalid: {email}")
-
编写一个正则表达式,匹配一个合法的手机号码(中国大陆)。
答案:import re pattern = r'^1[3-9]\d{9}$' phones = ["13800138000", "12345678901"] for phone in phones:if re.match(pattern, phone):print(f"Valid: {phone}")else:print(f"Invalid: {phone}")
-
编写一个正则表达式,匹配一个合法的 URL。
答案:import re pattern = r'https?://(?:www\.)?\S+' urls = ["https://www.example.com", "ftp://example.com"] for url in urls:if re.match(pattern, url):print(f"Valid: {url}")else:print(f"Invalid: {url}")
-
编写一个正则表达式,匹配一个合法的日期(YYYY-MM-DD)。
答案:import re pattern = r'^\d{4}-\d{2}-\d{2}$' dates = ["2023-10-05", "2023/10/05"] for date in dates:if re.match(pattern, date):print(f"Valid: {date}")else:print(f"Invalid: {date}")
-
编写一个正则表达式,匹配一个合法的强密码(至少 8 位,包含大小写字母、数字和特殊字符)。
答案:import re pattern = r'^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[\W_]).{8,}$' passwords = ["Password123!", "weakpass"] for pwd in passwords:if re.match(pattern, pwd):print(f"Strong: {pwd}")else:print(f"Weak: {pwd}")
总分:100 分
- 选择题:15 题 × 2 分 = 30 分
- 填空题:10 题 × 3 分 = 30 分
- 编程题:5 题 × 8 分 = 40 分
五、实战案例
本节内容包含 3 个关于“正则表达式”的综合应用项目,每个项目都包含完整的程序代码、测试案例、执行结果以及代码说明。具体项目是:
- 邮箱地址提取器
- 日志文件分析器
- HTML 标签提取器
项目 1:邮箱地址提取器
功能描述
从一段文本中提取所有合法的邮箱地址。
代码
import redef extract_emails(text):# 正则表达式匹配邮箱地址pattern = r'[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+'# 查找所有匹配的邮箱地址emails = re.findall(pattern, text)return emails# 测试案例
text = """
Contact us at support@example.com or sales@example.org.
For more information, visit https://www.example.com.
Invalid email: user@com.
"""
emails = extract_emails(text)
print("Extracted emails:", emails)
执行结果
Extracted emails: ['support@example.com', 'sales@example.org']
代码说明
- 使用正则表达式
[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+
匹配邮箱地址。 re.findall
返回所有匹配的邮箱地址。
项目 2:日志文件分析器
功能描述
从日志文件中提取所有错误日志(包含 “ERROR” 关键字)。
代码
import redef extract_errors(log_file):# 正则表达式匹配错误日志pattern = r'ERROR.*'errors = []with open(log_file, 'r') as file:for line in file:match = re.search(pattern, line)if match:errors.append(match.group())return errors# 测试案例
log_file = 'sample_log.txt'
# 假设 sample_log.txt 内容如下:
"""
INFO: User logged in
ERROR: Failed to connect to database
INFO: Request processed
ERROR: File not found
"""
errors = extract_errors(log_file)
print("Error logs:")
for error in errors:print(error)
执行结果
Error logs:
ERROR: Failed to connect to database
ERROR: File not found
代码说明
- 使用正则表达式
ERROR.*
匹配以 “ERROR” 开头的日志行。 - 逐行读取日志文件并提取匹配的错误日志。
项目 3:HTML 标签提取器
功能描述
从 HTML 文本中提取所有标签及其内容。
代码
import redef extract_html_tags(html):# 正则表达式匹配 HTML 标签及其内容pattern = r'<(\w+)[^>]*>(.*?)</\1>'tags = re.findall(pattern, html)return tags# 测试案例
html = """
<div class="header">Welcome</div>
<p>This is a <b>test</b> paragraph.</p>
<a href="https://example.com">Link</a>
"""
tags = extract_html_tags(html)
print("HTML tags and content:")
for tag, content in tags:print(f"Tag: {tag}, Content: {content}")
执行结果
HTML tags and content:
Tag: div, Content: Welcome
Tag: p, Content: This is a <b>test</b> paragraph.
Tag: a, Content: Link
代码说明
- 使用正则表达式
<(\w+)[^>]*>(.*?)</\1>
匹配 HTML 标签及其内容。 re.findall
返回所有匹配的标签及其内容。
小结
以上 3 个迷你项目展示了正则表达式在实际应用中的强大功能,包括文本提取、日志分析、HTML 处理等。通过这些项目,可以更好地理解和掌握正则表达式的使用。