第97集:re模块:正则表达式基础
学习目标
- 理解正则表达式的基本概念和作用
- 掌握Python中re模块的基本使用方法
- 学习正则表达式的基本语法规则
- 能够使用正则表达式进行简单的字符串匹配操作
一、什么是正则表达式?
正则表达式(Regular Expression,简称Regex或RegExp)是一种用于描述字符串模式的特殊语法,它可以帮助我们:
- 匹配特定模式的字符串
- 查找字符串中的特定内容
- 替换字符串中的特定部分
- 分割字符串
正则表达式广泛应用于文本处理、数据验证、信息提取等场景。
二、Python中的re模块
Python提供了内置的re模块,用于处理正则表达式。使用前需要先导入:
import re三、正则表达式的基本语法
1. 普通字符
普通字符包括字母、数字、空格等,它们在正则表达式中表示自身:
a匹配字符"a"123匹配字符串"123"hello匹配字符串"hello"
2. 元字符
元字符是正则表达式中具有特殊含义的字符:
| 元字符 | 含义 | 示例 |
|---|---|---|
. |
匹配任意单个字符(除了换行符) | a.b 匹配 "acb"、"a1b"、"a b" 等 |
^ |
匹配字符串的开头 | ^hello 匹配以 "hello" 开头的字符串 |
$ |
匹配字符串的结尾 | world$ 匹配以 "world" 结尾的字符串 |
* |
匹配前面的字符0次或多次 | ab*c 匹配 "ac"、"abc"、"abbc" 等 |
+ |
匹配前面的字符1次或多次 | ab+c 匹配 "abc"、"abbc" 等 |
? |
匹配前面的字符0次或1次 | ab?c 匹配 "ac"、"abc" |
{n} |
匹配前面的字符恰好n次 | ab{3}c 匹配 "abbbc" |
{n,} |
匹配前面的字符至少n次 | ab{2,}c 匹配 "abbc"、"abbbc" 等 |
{n,m} |
匹配前面的字符n到m次 | ab{1,3}c 匹配 "abc"、"abbc"、"abbbc" |
[] |
字符类,匹配括号内的任意一个字符 | [abc] 匹配 "a"、"b" 或 "c" |
\ |
转义字符,用于匹配特殊字符本身 | \. 匹配 ",\\ 匹配 "" |
| ` | ` | 或运算符,匹配左右任意一个表达式 |
() |
分组,将多个字符作为一个整体 | (ab)+ 匹配 "ab"、"abab" 等 |
3. 字符类
字符类用于匹配指定范围内的字符:
| 字符类 | 含义 |
|---|---|
[abc] |
匹配 "a"、"b" 或 "c" |
[a-z] |
匹配任意小写字母 |
[A-Z] |
匹配任意大写字母 |
[0-9] |
匹配任意数字 |
[a-zA-Z] |
匹配任意字母 |
[a-zA-Z0-9] |
匹配任意字母或数字 |
[^abc] |
匹配除了 "a"、"b"、"c" 之外的任意字符 |
4. 预定义字符类
为了方便使用,正则表达式提供了一些预定义的字符类:
| 预定义字符类 | 含义 | 等价于 |
|---|---|---|
\d |
匹配任意数字 | [0-9] |
\D |
匹配任意非数字 | [^0-9] |
\w |
匹配任意字母、数字或下划线 | [a-zA-Z0-9_] |
\W |
匹配任意非字母、数字或下划线 | [^a-zA-Z0-9_] |
\s |
匹配任意空白字符(空格、制表符、换行符等) | [ \t\n\r\f\v] |
\S |
匹配任意非空白字符 | [^ \t\n\r\f\v] |
5. 量词的贪婪与非贪婪
默认情况下,量词是贪婪的,会尽可能多地匹配字符。在量词后面加上?可以使其变为非贪婪模式:
.*贪婪匹配:匹配尽可能多的字符.*?非贪婪匹配:匹配尽可能少的字符
四、re模块的常用函数
1. re.match()
re.match() 尝试从字符串的开头匹配一个模式:
import re
# 匹配成功
result = re.match(r'hello', 'hello world')
print(result) # <re.Match object; span=(0, 5), match='hello'>
print(result.group()) # hello
print(result.span()) # (0, 5)
# 匹配失败
result = re.match(r'world', 'hello world')
print(result) # None2. re.search()
re.search() 在整个字符串中查找第一个匹配的模式:
import re
result = re.search(r'world', 'hello world')
print(result) # <re.Match object; span=(6, 11), match='world'>
print(result.group()) # world3. re.findall()
re.findall() 查找字符串中所有匹配的模式,返回一个列表:
import re
result = re.findall(r'\d+', 'There are 123 apples and 456 oranges')
print(result) # ['123', '456']4. re.split()
re.split() 根据匹配的模式分割字符串:
import re
# 用逗号或空格分割字符串
result = re.split(r'[ ,]+', 'a,b c d')
print(result) # ['a', 'b', 'c', 'd']5. re.sub()
re.sub() 替换字符串中匹配的模式:
import re
# 将所有数字替换为 "X"
result = re.sub(r'\d+', 'X', 'There are 123 apples and 456 oranges')
print(result) # There are X apples and X oranges6. re.compile()
re.compile() 编译正则表达式模式,提高多次使用的效率:
import re
# 编译模式
pattern = re.compile(r'\d+')
# 使用编译后的模式
result1 = pattern.findall('123 abc 456')
result2 = pattern.sub('X', '789 def 012')
print(result1) # ['123', '456']
print(result2) # X def X五、分组
使用括号 () 可以将正则表达式的一部分分组,方便后续操作:
import re
# 匹配日期格式:YYYY-MM-DD
pattern = re.compile(r'(\d{4})-(\d{2})-(\d{2})')
result = pattern.match('2023-10-05')
if result:
print(result.group()) # 2023-10-05 (完整匹配)
print(result.group(1)) # 2023 (第1组)
print(result.group(2)) # 10 (第2组)
print(result.group(3)) # 05 (第3组)
print(result.groups()) # ('2023', '10', '05') (所有组)六、应用案例
1. 验证邮箱格式
import re
def is_valid_email(email):
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return bool(re.match(pattern, email))
# 测试
print(is_valid_email('user@example.com')) # True
print(is_valid_email('invalid-email')) # False
print(is_valid_email('another.user@sub.example.org')) # True2. 提取URL
import re
def extract_urls(text):
pattern = r'https?://[\w\-._~:/?#[\]@!$&\'()*+,;=.]+'
return re.findall(pattern, text)
# 测试
text = 'Visit https://www.example.com or http://test.org for more info.'
print(extract_urls(text)) # ['https://www.example.com', 'http://test.org']3. 替换电话号码格式
import re
def format_phone_number(phone):
# 将电话号码格式化为 (XXX) XXX-XXXX
pattern = r'(\d{3})(\d{3})(\d{4})'
return re.sub(pattern, r'(\1) \2-\3', phone)
# 测试
print(format_phone_number('1234567890')) # (123) 456-7890七、最佳实践
使用原始字符串:在正则表达式前加上
r表示原始字符串,避免转义字符的问题:# 推荐 pattern = r'\d+' # 不推荐 pattern = '\\d+'编译正则表达式:如果需要多次使用同一个正则表达式,建议先编译:
pattern = re.compile(r'\d+') result1 = pattern.findall(text1) result2 = pattern.findall(text2)注意贪婪与非贪婪:根据需要选择合适的量词模式
测试正则表达式:使用在线工具(如regex101.com)测试正则表达式
保持正则表达式的可读性:复杂的正则表达式可以使用注释(通过
re.VERBOSE标志)
八、总结
本集我们学习了:
- 正则表达式的基本概念和作用
- Python中re模块的导入和使用
- 正则表达式的基本语法(普通字符、元字符、字符类、量词等)
- re模块的常用函数(match、search、findall、split、sub、compile)
- 分组的使用方法
- 正则表达式的应用案例和最佳实践
正则表达式是一个强大的工具,但也需要不断练习才能熟练掌握。下一集我们将深入学习re模块的高级功能。
九、课后练习
- 编写一个正则表达式,匹配中国的手机号码(11位数字,以1开头)
- 使用正则表达式从以下文本中提取所有的IP地址:"Server 1: 192.168.1.1, Server 2: 10.0.0.1"
- 编写一个函数,将字符串中的多余空格替换为单个空格
- 使用正则表达式验证密码强度(至少8位,包含大小写字母和数字)
下一集预告:re模块:模式匹配(第98集)