Python 中的正则表达式是通过 re
模块实现的,它提供了强大的字符串模式匹配功能。下面是正则表达式的基本用法和常见模式:
首先需要导入 re
模块:
import re
# 匹配单个字符
re.match(r'a', 'abc') # 匹配字母 'a'
re.match(r'.', 'abc') # 匹配任意单个字符(除了换行符)
re.match(r'\d', '123') # 匹配任意数字,等价于 [0-9]
re.match(r'\D', 'abc') # 匹配任意非数字,等价于 [^0-9]
re.match(r'\w', 'a1_') # 匹配任意字母、数字或下划线,等价于 [a-zA-Z0-9_]
re.match(r'\W', '@#$') # 匹配任意非字母、数字或下划线,等价于 [^a-zA-Z0-9_]
re.match(r'\s', ' \t\n') # 匹配任意空白字符,包括空格、制表符、换行符等
re.match(r'\S', 'a') # 匹配任意非空白字符
re.match(r'[abc]', 'a') # 匹配 'a'、'b' 或 'c' 中的任意一个字符
re.match(r'[a-z]', 'x') # 匹配小写字母
re.match(r'[A-Z]', 'X') # 匹配大写字母
re.match(r'[0-9]', '5') # 匹配数字
re.match(r'[^abc]', 'd') # 匹配除了 'a'、'b'、'c' 之外的任意字符
re.match(r'a*', 'aaa') # 匹配 0 个或多个 'a'
re.match(r'a+', 'aaa') # 匹配 1 个或多个 'a'
re.match(r'a?', 'a') # 匹配 0 个或 1 个 'a'
re.match(r'a{3}', 'aaa') # 匹配恰好 3 个 'a'
re.match(r'a{3,}', 'aaaa') # 匹配至少 3 个 'a'
re.match(r'a{3,5}', 'aaaa') # 匹配 3 到 5 个 'a'
re.match(r'a\.b', 'a.b') # 匹配字面点号
re.match(r'a\\b', 'a\\b') # 匹配字面反斜杠
re.match(r'a\?', 'a?') # 匹配字面问号
re.match(r'a\*', 'a*') # 匹配字面星号
re.match(r'a\+', 'a+') # 匹配字面加号
re.match(r'^a', 'abc') # 匹配字符串开头的 'a'
re.match(r'b$', 'ab') # 匹配字符串结尾的 'b'
re.search(r'\ba', 'abc') # 匹配单词边界的 'a'
re.search(r'a\b', 'ab') # 匹配单词边界的 'a'
match = re.match(r'(\d{3})-(\d{4})', '123-4567')
print(match.group(0)) # 整个匹配:123-4567
print(match.group(1)) # 第一个分组:123
print(match.group(2)) # 第二个分组:4567
pattern = r'[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+'
email = '[email protected]'
if re.match(pattern, email):
print("有效的邮箱地址")
text = 'Hello, World! Hello, Python!'
new_text = re.sub(r'Hello', 'Hi', text)
print(new_text) # 输出: Hi, World! Hi, Python!
text = 'apple,banana;cherry apple'
fruits = re.split(r'[;,\s]+', text)
print(fruits) # 输出: ['apple', 'banana', 'cherry', 'apple']
text = 'Hello 123 World 456'
numbers = re.findall(r'\d+', text)
print(numbers) # 输出: ['123', '456']
正则表达式函数可以接受标志参数,常用的标志有:
^
和 $
text = 'Hello\nWorld'
matches = re.findall(r'.+', text, re.DOTALL)
print(matches) # 输出: ['Hello\nWorld']
这些是 Python 正则表达式的基础知识。正则表达式是一个强大的工具,但也很复杂,建议通过练习和参考官方文档来掌握更多高级用法。
正则表达式是处理文本的强大工具,掌握进阶技巧可以大大提高效率。以下是 Python 正则表达式的一些进阶知识点:
# 贪婪匹配(默认)
text = 'content'
re.findall(r'<.*>', text) # 返回: ['content']
# 非贪婪匹配(使用 ?)
re.findall(r'<.*?>', text) # 返回: ['', '']
# 前瞻断言:(?=pattern)
text = 'apple123 banana456'
re.findall(r'\w+(?=\d+)', text) # 返回: ['apple', 'banana']
# 负前瞻断言:(?!pattern)
re.findall(r'\w+(?!\d+)', text) # 返回: []
# 后瞻断言:(?<=pattern)
text = '¥100 $200'
re.findall(r'(?<=\$)\d+', text) # 返回: ['200']
# 负后瞻断言:(?
# 使用 (?(group)yes-pattern|no-pattern)
text = '123-456'
pattern = r'(\d{3})?(?:-)?(?(1)\d{3}|\d{6})'
re.match(pattern, text) # 匹配成功
text = '2025-05-15'
pattern = r'(?P\d{4})-(?P\d{2})-(?P\d{2})'
match = re.match(pattern, text)
print(match.group('year')) # 输出: 2025
print(match.groupdict()) # 输出: {'year': '2025', 'month': '05', 'day': '15'}
text = 'hello hello world'
pattern = r'(\b\w+\b)\s+\1' # 引用第一个分组
re.findall(pattern, text) # 返回: ['hello']
text = 'ababab'
pattern = r'(?:ab)+' # 非捕获分组,不存储匹配结果
re.findall(pattern, text) # 返回: ['ababab']
# 编译正则表达式提高性能
pattern = re.compile(r'\d+')
text = 'abc123def456'
pattern.findall(text) # 返回: ['123', '456']
# 编译时使用标志
pattern = re.compile(r'^hello', re.MULTILINE)
text = 'hello world\nhello python'
pattern.findall(text) # 返回: ['hello', 'hello']
def double_number(match):
return str(int(match.group(0)) * 2)
text = '10 20 30'
re.sub(r'\d+', double_number, text) # 返回: '20 40 60'
text = '2025-05-15'
re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\3/\2/\1', text) # 返回: '15/05/2025'
text = '''
Test
Hello World
'''
# 使用 DOTALL 标志匹配跨行内容
re.findall(r'(.*?)', text, re.DOTALL) # 返回: ['\nHello World\n']
text = '''line 1
line 2
line 3'''
# 使用 MULTILINE 标志匹配每行的开头
re.findall(r'^line', text, re.MULTILINE) # 返回: ['line', 'line', 'line']
预编译常用模式:对于频繁使用的正则表达式,先编译再使用可以提高性能。
简化模式:复杂的模式会降低匹配速度,尽量使用简单的模式。
避免回溯:过多的回溯会导致性能下降,例如嵌套的重复模式。
使用非贪婪匹配:在不需要贪婪匹配的地方使用非贪婪匹配。
html = 'Example Test'
links = re.findall(r'href="(https?://[^"]+)"', html)
print(links) # 返回: ['https://example.com', 'http://test.com']
password = 'Abc123!'
pattern = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$'
if re.match(pattern, password):
print("密码强度符合要求")
csv = 'name,age,city\nAlice,25,New York\nBob,30,Los Angeles'
rows = re.split(r'\n', csv)
data = [re.split(r',', row) for row in rows]
print(data) # 返回: [['name', 'age', 'city'], ['Alice', '25', 'New York'], ['Bob', '30', 'Los Angeles']]
正则表达式可能很复杂,调试时可以使用以下工具:
pattern = re.compile(r'a(b*)c', re.DEBUG)
正则表达式是一个强大但复杂的工具,建议通过练习和实践来掌握这些进阶技巧。对于特别复杂的文本处理任务,也可以考虑结合字符串方法和正则表达式使用,以获得更好的可读性和性能。