文章目录
一、正则表达式基础概念
1.1 什么是正则表达式
1.2 正则表达式的基本组成元素
1.3 Python re模块简介
二、re模块的基本使用
2.1 导入re模块
2.2 简单的正则匹配示例
2.3 正则表达式的编译与重用
2.4 原始字符串(raw string)的重要性
三、常用正则表达式模式
3.1 基本元字符
3.2 字符类
3.3 预定义字符类
3.4 边界匹配
3.5 贪婪与非贪婪匹配
四、匹配与搜索操作
4.1 re.match() vs re.search()
4.2 匹配对象的方法
4.3 re.findall() 和 re.finditer()
4.4 匹配标志(flags)
五、分组与捕获
5.1 基本分组
5.2 非捕获分组
5.3 命名分组
5.4 分组引用
5.5 条件匹配
六、替换操作
6.1 re.sub() 基本使用
6.2 使用函数进行替换
6.3 引用分组进行替换
6.4 re.subn()
七、高级正则表达式技巧
7.1 前后查找断言
7.2 注释与复杂模式
7.3 递归模式
7.4 Unicode匹配
八、性能优化与最佳实践
8.1 编译正则表达式
8.2 避免回溯灾难
8.3 使用原子组防止回溯
8.4 正则表达式最佳实践
九、实际应用案例
9.1 验证电子邮件地址
9.2 提取URL信息
9.3 日志文件分析
9.4 数据清洗
十、常见问题与解决方案
10.1 正则表达式常见陷阱
10.2 调试正则表达式
10.3 何时不使用正则表达式
十一、总结与扩展
11.1 核心知识点回顾
11.2 扩展学习资源
11.3 实际应用建议
一、正则表达式基础概念
1.1 什么是正则表达式
正则表达式(Regular Expression,简称regex或re)是一种强大的文本处理工具,它使用特定模式的字符串来描述、匹配一系列符合某个句法规则的字符串。本质上,正则表达式是一种微型语言,专门用于字符串的模式匹配和文本处理。
在编程领域,正则表达式被广泛应用于:
数据验证(如邮箱、电话号码格式检查)
文本搜索与替换
数据提取(从非结构化文本中提取结构化数据)
字符串分割
语法高亮和许多其他文本处理任务
Python通过内置的re模块提供了完整的正则表达式功能,该模块包含了所有必要的函数和方法来执行各种正则表达式操作。
1.2 正则表达式的基本组成元素
正则表达式由普通字符和特殊字符(称为”元字符”)组成。以下是正则表达式的基本构建块:
| 元素类型 | 说明 | 示例 |
|---|---|---|
| 字面字符 | 匹配自身的普通字符 | a 匹配字符”a” |
| 元字符 | 具有特殊含义的字符 | . 匹配任意字符 |
| 字符类 | 匹配一组字符中的任意一个 | [abc] 匹配a/b/c |
| 量词 | 指定匹配的次数 | a{3} 匹配”aaa” |
| 锚点 | 指定匹配的位置 | ^ 匹配行首 |
| 分组与捕获 | 将多个元素组合为一个单元,并可捕获匹配内容 | (abc) |
| 转义序列 | 使用反斜杠改变字符的含义 | d 匹配数字 |
1.3 Python re模块简介
Python的re模块提供了正则表达式支持,包含以下主要功能:
模式匹配:检查字符串是否匹配特定模式
搜索:在字符串中查找模式出现的位置
替换:将匹配模式的部分替换为其他文本
分割:根据模式分割字符串
re模块的核心函数包括:
import re
# 主要函数
re.match() # 从字符串起始位置匹配模式
re.search() # 搜索字符串中第一个匹配项
re.findall() # 查找所有匹配项并以列表返回
re.finditer() # 查找所有匹配项并返回迭代器
re.sub() # 替换匹配项
re.split() # 根据模式分割字符串
re.compile() # 将正则表达式编译为模式对象
二、re模块的基本使用
2.1 导入re模块
在Python中使用正则表达式前,首先需要导入re模块:
import re
2.2 简单的正则匹配示例
让我们从一个最简单的例子开始,检查字符串是否包含”Python”:
pattern = r"Python" # 模式字符串前面的'r'表示原始字符串,避免转义字符的问题
text = "I love Python programming"
# 使用re.search()查找匹配
match = re.search(pattern, text)
if match:
print("Found:", match.group()) # 输出匹配的内容
else:
print("Not found")
输出:
Found: Python
2.3 正则表达式的编译与重用
对于需要多次使用的正则表达式,可以先编译它以提高效率:
# 编译正则表达式
pattern = re.compile(r"Python")
# 使用编译后的模式对象进行多次匹配
text1 = "I love Python"
text2 = "Python is awesome"
print(pattern.search(text1).group()) # 输出: Python
print(pattern.search(text2).group()) # 输出: Python
编译正则表达式的优点:
性能提升:避免每次匹配时重新编译模式
代码可读性:将模式定义与使用分离
方法链调用:编译后的模式对象可以直接调用方法
2.4 原始字符串(raw string)的重要性
在Python中编写正则表达式时,强烈建议使用原始字符串(在字符串前加r),这是因为:
正则表达式本身使用反斜杠()作为转义字符
Python字符串也使用反斜杠作为转义字符
原始字符串可以避免双重转义的问题
对比示例:
# 不使用原始字符串
print("\section") # 需要两个反斜杠才能表示一个实际的反斜杠
# 使用原始字符串
print(r"section") # 直接表示反斜杠
在正则表达式中,这种区别尤为重要:
# 匹配一个数字后跟一个点,如"1.", "2."等
# 不使用原始字符串 - 需要四个反斜杠!
pattern1 = "\d\."
# 使用原始字符串 - 只需要两个反斜杠
pattern2 = r"d."
text = "Section 1. Introduction"
print(re.search(pattern1, text).group()) # 输出: 1.
print(re.search(pattern2, text).group()) # 输出: 1.
三、常用正则表达式模式
3.1 基本元字符
正则表达式的强大之处在于其元字符的使用,以下是核心元字符及其功能:
| 元字符 | 描述 | 示例 | 匹配示例 |
|---|---|---|---|
| . | 匹配除换行符外的任意单个字符 | a.b | “aab”, “a7b”, “a b” |
| ^ | 匹配字符串的开始 | ^Hello | “Hello world” |
| $ | 匹配字符串的结束 | world$ | “Hello world” |
| * | 匹配前一个字符0次或多次 | ab*c | “ac”, “abc”, “abbc” |
| + | 匹配前一个字符1次或多次 | ab+c | “abc”, “abbc” |
| ? | 匹配前一个字符0次或1次 | ab?c | “ac”, “abc” |
| {m} | 匹配前一个字符恰好m次 | a{3} | “aaa” |
| {m,n} | 匹配前一个字符至少m次,至多n次 | a{2,4} | “aa”, “aaa”, “aaaa” |
| 转义字符,使特殊字符失去特殊含义 | . | 匹配”.”字符 | |
| | | 或操作,匹配左边或右边的表达式 | cat|dog | “cat”, “dog” |
3.2 字符类
字符类用于匹配一组字符中的任意一个:
| 模式 | 描述 | 示例 | 匹配示例 |
|---|---|---|---|
| [abc] | 匹配a、b或c | [abc]at | “aat”, “bat” |
| [a-z] | 匹配任何小写字母 | [a-z] | “a”, “b”, “z” |
| [A-Z] | 匹配任何大写字母 | [A-Z] | “A”, “B”, “Z” |
| [0-9] | 匹配任何数字 | [0-9] | “0”, “1”, “9” |
| [^abc] | 匹配除了a、b、c之外的任何字符 | [^abc]at | “dat”, “fat” |
| [a-zA-Z0-9] | 匹配任何字母或数字 | [a-zA-Z0-9] | “a”, “B”, “7” |
3.3 预定义字符类
为了简化常用字符类的编写,正则表达式提供了一些预定义字符类:
| 模式 | 等价于 | 描述 |
|---|---|---|
| d | [0-9] | 匹配任何数字字符 |
| D | [^0-9] | 匹配任何非数字字符 |
| s | [
fv] |
匹配任何空白字符(空格、制表符等) |
| S | [^
fv] |
匹配任何非空白字符 |
| w | [a-zA-Z0-9_] | 匹配任何字母数字字符(单词字符) |
| W | [^a-zA-Z0-9_] | 匹配任何非单词字符 |
3.4 边界匹配
边界匹配用于指定匹配发生的位置:
| 模式 | 描述 | 示例 | 匹配示例 |
|---|---|---|---|
| 匹配单词边界 | foo | “foo” in “foo bar” | |
| B | 匹配非单词边界 | BfooB | “foo” in “foobar” |
| ^ | 匹配字符串开始 | ^Start | “Start” at beginning |
| $ | 匹配字符串结束 | end$ | “end” at end |
| A | 仅匹配字符串开始 | AStart | Similar to ^ |
| 仅匹配字符串结束 | end | Similar to $ |
3.5 贪婪与非贪婪匹配
正则表达式默认采用贪婪匹配模式,即尽可能匹配更长的字符串。可以在量词后加?来启用非贪婪模式:
text = "<h1>Title</h1><h2>Subtitle</h2>"
# 贪婪匹配 - 匹配最长的可能字符串
greedy_pattern = r"<.*>"
print(re.search(greedy_pattern, text).group())
# 输出: <h1>Title</h1><h2>Subtitle</h2>
# 非贪婪匹配 - 匹配最短的可能字符串
non_greedy_pattern = r"<.*?>"
print(re.findall(non_greedy_pattern, text))
# 输出: ['<h1>', '</h1>', '<h2>', '</h2>']
四、匹配与搜索操作
4.1 re.match() vs re.search()
re.match()和re.search()是re模块中两个基本的匹配函数,它们的区别如下:
| 函数 | 匹配位置 | 返回值 | 适用场景 |
|---|---|---|---|
| re.match() | 仅从字符串开始处匹配 | 匹配对象或None | 检查字符串是否符合特定模式 |
| re.search() | 扫描整个字符串查找匹配 | 匹配对象或None | 查找字符串中是否存在某个模式 |
示例:
text = "Python is awesome"
# match只在字符串开头匹配
print(re.match(r"Python", text)) # 匹配成功
print(re.match(r"awesome", text)) # 匹配失败
# search在整个字符串中搜索
print(re.search(r"Python", text)) # 匹配成功
print(re.search(r"awesome", text)) # 匹配成功
4.2 匹配对象的方法
当匹配成功时,match()和search()返回一个匹配对象,该对象有以下常用方法:
| 方法 | 描述 |
|---|---|
| group() | 返回匹配的字符串,可以传入分组编号获取特定分组 |
| groups() | 返回包含所有分组的元组 |
| start() | 返回匹配的开始位置 |
| end() | 返回匹配的结束位置 |
| span() | 返回一个元组包含匹配的(开始,结束)位置 |
示例:
text = "My email is example@email.com"
match = re.search(r"(w+)@(w+.w+)", text)
if match:
print("Full match:", match.group()) # example@email.com
print("Username:", match.group(1)) # example
print("Domain:", match.group(2)) # email.com
print("All groups:", match.groups()) # ('example', 'email.com')
print("Match positions:", match.span()) # (11, 27)
4.3 re.findall() 和 re.finditer()
re.findall()和re.finditer()用于查找所有匹配项:
findall(): 返回所有匹配项的列表(或元组列表,如果有分组)
finditer(): 返回一个迭代器,产生匹配对象
示例:
text = "Colors: red, blue, green, yellow"
# 使用findall查找所有颜色
colors = re.findall(r"w+", text)
print(colors) # ['Colors', 'red', 'blue', 'green', 'yellow']
# 使用finditer获取更多匹配信息
for match in re.finditer(r"w+", text):
print(f"'{
match.group()}' found at positions {
match.span()}")
输出:
'Colors' found at positions (0, 6)
'red' found at positions (8, 11)
'blue' found at positions (13, 17)
'green' found at positions (19, 24)
'yellow' found at positions (26, 32)
4.4 匹配标志(flags)
re模块提供了一些标志来修改匹配行为,常用的有:
| 标志 | 描述 |
|---|---|
| re.IGNORECASE (re.I) | 使匹配对大小写不敏感 |
| re.MULTILINE (re.M) | 使^和$匹配每行的开始和结束,而不仅是整个字符串 |
| re.DOTALL (re.S) | 使.匹配包括换行符在内的所有字符 |
| re.VERBOSE (re.X) | 允许在正则表达式中添加注释和空白,使其更易读 |
示例:
text = "Python
python
PYTHON"
# 不区分大小写匹配
print(re.findall(r"python", text, re.IGNORECASE))
# 输出: ['Python', 'python', 'PYTHON']
# 多行模式匹配
print(re.findall(r"^py", text, re.I | re.M))
# 输出: ['Py', 'py']
五、分组与捕获
5.1 基本分组
分组使用圆括号()创建,主要有两个用途:
将多个模式元素组合为一个单元
捕获匹配的子字符串
示例:
text = "John Doe, Jane Smith, Bob Johnson"
# 匹配姓氏和名字并捕获
matches = re.findall(r"(w+) (w+)", text)
print(matches)
# 输出: [('John', 'Doe'), ('Jane', 'Smith'), ('Bob', 'Johnson')]
5.2 非捕获分组
有时我们需要分组但不捕获内容,可以使用(?:...)语法:
text = "color colour"
# 捕获分组
print(re.findall(r"col(o|ou)r", text)) # ['o', 'ou']
# 非捕获分组
print(re.findall(r"col(?:o|ou)r", text)) # ['color', 'colour']
5.3 命名分组
Python正则表达式支持命名分组,语法为(?P<name>...):
text = "Date: 2023-05-15"
match = re.search(r"Date: (?P<year>d{4})-(?P<month>d{2})-(?P<day>d{2})", text)
if match:
print("Year:", match.group("year")) # 2023
print("Month:", match.group("month")) # 05
print("Day:", match.group("day")) # 15
print(match.groupdict()) # {'year': '2023', 'month': '05', 'day': '15'}
5.4 分组引用
可以在正则表达式中引用前面的分组:
:引用第n个分组(n为数字)
(?P=name):引用命名分组
示例:
# 查找重复的单词
text = "the the quick brown fox jumps over the the lazy dog"
print(re.findall(r"(w+)s+1", text)) # ['the', 'the']
# 使用命名分组引用
print(re.findall(r"(?P<word>w+)s+(?P=word)", text)) # ['the', 'the']
5.5 条件匹配
正则表达式支持基于分组匹配结果的条件判断:
语法:(?(id/name)yes-pattern|no-pattern)
示例:
# 匹配带有或不带有区号的电话号码
texts = ["123-4567", "(123) 456-7890", "456-7890"]
pattern = r"((d{3})s)?d{3}-?d{4}(?(1)|d{0})"
for text in texts:
match = re.search(pattern, text)
if match:
print(f"Matched: {
match.group()}")
六、替换操作
6.1 re.sub() 基本使用
re.sub()用于替换字符串中的匹配项:
text = "The rain in Spain falls mainly in the plain."
# 将所有"in"替换为"IN"
new_text = re.sub(r"in", "IN", text)
print(new_text)
# 输出: The rain IN Spain falls mainly IN the plain.
6.2 使用函数进行替换
re.sub()可以接受一个函数作为替换参数,该函数接收匹配对象作为参数:
def to_upper(match):
return match.group().upper()
text = "hello world"
new_text = re.sub(r"w+", to_upper, text)
print(new_text) # HELLO WORLD
6.3 引用分组进行替换
在替换字符串中可以使用或
g<name>引用分组:
# 重新格式化日期
text = "Today is 05-15-2023"
new_text = re.sub(r"(d{2})-(d{2})-(d{4})", r"3年1月2日", text)
print(new_text) # Today is 2023年05月15日
# 使用命名分组
new_text = re.sub(r"(?P<month>d{2})-(?P<day>d{2})-(?P<year>d{4})",
r"g<year>年g<month>月g<day>日", text)
print(new_text) # Today is 2023年05月15日
6.4 re.subn()
re.subn()与re.sub()功能相同,但返回一个元组(新字符串, 替换次数):
text = "foo bar baz foo"
result = re.subn(r"foo", "FOO", text)
print(result) # ('FOO bar baz FOO', 2)
七、高级正则表达式技巧
7.1 前后查找断言
前后查找断言用于指定匹配的前后条件,但不包含这些条件在实际匹配中:
| 断言类型 | 语法 | 描述 |
|---|---|---|
| 正向先行断言 | (?=…) | 匹配后面跟着…的位置 |
| 负向先行断言 | (?!..) | 匹配后面不跟着…的位置 |
| 正向后行断言 | (?<=…) | 匹配前面是…的位置 |
| 负向后行断言 | (?<!..) | 匹配前面不是…的位置 |
示例:
# 正向先行断言 - 匹配后面跟着"元"的数字
text = "10元 20美元 30元 40英镑"
print(re.findall(r"d+(?=元)", text)) # ['10', '30']
# 正向后行断言 - 匹配前面是"$"的数字
text = "Price: $100, €200, $300"
print(re.findall(r"(?<=$)d+", text)) # ['100', '300']
# 组合使用 - 匹配价格但不包括货币符号
text = "价格: ¥2000, $150, €300"
print(re.findall(r"(?<=¥|$|€)d+", text)) # ['2000', '150', '300']
7.2 注释与复杂模式
使用re.VERBOSE标志可以让复杂的正则表达式更易读:
pattern = re.compile(r"""
^ # 字符串开始
(d{3}) # 3位区号
[-s]? # 可选的连接符或空格
(d{3}) # 3位交换码
[-s]? # 可选的连接符或空格
(d{4}) # 4位线路号
$ # 字符串结束
""", re.VERBOSE)
text = "123-456-7890"
match = pattern.search(text)
if match:
print("Phone number:", match.group()) # 123-456-7890
7.3 递归模式
Python的regex模块(非标准库)支持递归模式,可以匹配嵌套结构:
import regex # 需要安装: pip install regex
# 匹配平衡的括号
text = "((a + b) * (c - d))"
pattern = r"((?:[^()]|(?R))*)"
match = regex.search(pattern, text)
if match:
print("Matched:", match.group()) # ((a + b) * (c - d))
7.4 Unicode匹配
Python的正则表达式支持Unicode字符匹配:
# 匹配中文字符
text = "中文English混合字符串"
print(re.findall(r"[u4e00-u9fff]+", text)) # ['中文', '混合字符串']
# 匹配任何语言的字母
print(re.findall(r"w+", text, re.UNICODE)) # ['中文English混合字符串']
八、性能优化与最佳实践
8.1 编译正则表达式
对于频繁使用的正则表达式,预编译可以显著提高性能:
# 不好的做法 - 每次调用都重新编译
for i in range(10000):
re.match(r"d+", str(i))
# 好的做法 - 预编译正则表达式
pattern = re.compile(r"d+")
for i in range(10000):
pattern.match(str(i))
8.2 避免回溯灾难
复杂的正则表达式可能导致”回溯灾难”(catastrophic backtracking),使匹配时间指数级增长:
# 有问题的模式 - 可能导致性能问题
pattern = r"(a+)+b"
text = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaac" # 不匹配但会消耗大量时间
# 改进版本
better_pattern = r"a+b" # 更简单直接的表达
8.3 使用原子组防止回溯
原子组((?>...))一旦匹配成功就不会回溯:
# 普通分组 - 可能回溯
print(re.match(r"(a+)b", "aaaac")) # None (但会尝试所有可能性)
# 原子组 - 匹配失败更快
print(re.match(r"(?>a+)b", "aaaac")) # None (立即失败)
8.4 正则表达式最佳实践
保持简单:能用简单模式就不要用复杂模式
明确边界:使用或锚点(^, $)明确匹配边界
具体化:尽可能具体地描述要匹配的内容
测试边界条件:测试各种可能的输入,包括不匹配的情况
添加注释:复杂正则表达式使用re.VERBOSE和注释
性能测试:对大量数据测试正则表达式性能
九、实际应用案例
9.1 验证电子邮件地址
def validate_email(email):
pattern = r"""
^ # 开始
[a-zA-Z0-9._%+-]+ # 用户名
@ # @符号
[a-zA-Z0-9.-]+ # 域名
. # 点
[a-zA-Z]{2,} # 顶级域名
$ # 结束
"""
return bool(re.match(pattern, email, re.VERBOSE))
emails = [
"user@example.com", # 有效
"first.last@example.co.uk", # 有效
"invalid@.com", # 无效
"no@tld", # 无效
]
for email in emails:
print(f"{
email}: {
'Valid' if validate_email(email) else 'Invalid'}")
9.2 提取URL信息
def extract_url_info(url):
pattern = r"""
^(https?://) # 协议
(?:www.)? # 可选的www子域名
([a-zA-Z0-9-]+) # 主域名
. # 点
([a-zA-Z]{2,}) # 顶级域名
(?:/[^s]*)? # 可选的路径
$ # 结束
"""
match = re.match(pattern, url, re.VERBOSE)
if match:
return {
"protocol": match.group(1),
"domain": match.group(2),
"tld": match.group(3),
"full_domain": f"{
match.group(2)}.{
match.group(3)}"
}
return None
urls = [
"https://www.example.com/path/to/page",
"http://example.org",
"ftp://invalid.com"
]
for url in urls:
print(f"{
url}: {
extract_url_info(url)}")
9.3 日志文件分析
log_entry = """
2023-05-15 14:30:45,678 [ERROR] [MainThread] [module.py:123] This is an error message
2023-05-15 14:31:10,123 [INFO] [Worker-1] [utils.py:45] Processing completed
"""
pattern = r"""
^
(?P<timestamp>d{4}-d{2}-d{2}sd{2}:d{2}:d{2},d{3}) # 时间戳
s
[(?P<level>w+)] # 日志级别
s
[(?P<thread>[w-]+)] # 线程名
s
[(?P<module>[w.]+):(?P<line>d+)] # 模块和行号
s
(?P<message>.*) # 日志消息
$
"""
for line in log_entry.strip().split("
"):
match = re.match(pattern, line, re.VERBOSE)
if match:
print(f"Level: {
match.group('level')}, Module: {
match.group('module')}")
print(f"Message: {
match.group('message')}
")
9.4 数据清洗
dirty_data = """
Name: John Doe, Age: 30, Email: john@example.com
Name: Jane Smith, Age: twenty-five, Email: jane@example
Name: Bob, Age: 45, Email: bob@example.com
"""
# 提取有效记录
pattern = r"""
Name:s(?P<name>[^,]+),s
Age:s(?P<age>d+),s
Email:s(?P<email>S+@S+.S+)
"""
clean_records = []
for match in re.finditer(pattern, dirty_data, re.VERBOSE):
clean_records.append(match.groupdict())
print("Clean data:")
for record in clean_records:
print(record)
十、常见问题与解决方案
10.1 正则表达式常见陷阱
贪婪匹配:默认的贪婪匹配可能导致意外结果
解决方案:使用非贪婪量词(*?, +?, ??)
回溯灾难:复杂模式可能导致极慢的匹配
解决方案:简化模式,使用原子组,避免嵌套量词
Unicode问题:w, d等在不同环境下行为不同
解决方案:明确指定re.UNICODE标志或使用特定字符类
多行匹配:^和$默认只匹配字符串开始/结束
解决方案:使用re.MULTILINE标志
10.2 调试正则表达式
分步测试:从简单模式开始,逐步增加复杂度
在线工具:使用regex101.com等工具可视化匹配过程
打印中间结果:在复杂模式中插入打印语句
使用re.DEBUG:查看正则表达式如何被编译
re.compile(r"d{3}-d{4}", re.DEBUG)
10.3 何时不使用正则表达式
虽然正则表达式强大,但并非所有文本处理问题都适合:
结构化数据:如XML/JSON,使用专用解析器更合适
复杂语法:如编程语言解析,需要更专业的工具
性能敏感:对大量数据简单字符串操作可能更快
可读性:过于复杂的正则表达式难以维护
十一、总结与扩展
11.1 核心知识点回顾
基础语法:元字符、字符类、量词、锚点等构建块
re模块函数:match、search、findall、sub等核心函数
分组与捕获:基本分组、命名分组、非捕获分组
高级特性:前后查找断言、条件匹配、递归模式
性能优化:预编译、避免回溯灾难、原子组
11.2 扩展学习资源
官方文档:Python re模块官方文档
书籍:
《精通正则表达式》(Jeffrey Friedl)
《Python Cookbook》中相关章节
在线工具:
regex101.com – 交互式正则表达式测试器
debuggex.com – 正则表达式可视化工具
11.3 实际应用建议
项目中使用:将常用正则表达式集中管理,便于维护
文档化:为复杂正则表达式添加详细注释
单元测试:为正则表达式编写测试用例,覆盖各种边界情况
性能监控:对处理大量数据的正则表达式进行性能分析
# 示例:正则表达式工具类
class RegexUtils:
"""常用正则表达式工具集合"""
EMAIL = re.compile(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}$")
PHONE = re.compile(r"^(d{3})-(d{3})-(d{4})$")
URL = re.compile(r"^(https?)://([^/]+)(/.*)?$")
@classmethod
def is_valid_email(cls, email):
return bool(cls.EMAIL.match(email))
@classmethod
def extract_phone_parts(cls, phone):
match = cls.PHONE.match(phone)
return match.groups() if match else None
# 使用示例
print(RegexUtils.is_valid_email("test@example.com")) # True
print(RegexUtils.extract_phone_parts("123-456-7890")) # ('123', '456', '7890')
正则表达式是Python程序员工具箱中极其强大的工具,掌握它可以显著提高文本处理能力。通过本指南的系统学习,您应该已经建立了扎实的正则表达式基础,并能够在实际项目中有效应用这些知识。记住,正则表达式技能需要通过实践不断磨练,遇到复杂模式时不妨分解问题、逐步构建解决方案。


















暂无评论内容