Python正则表达式入门与进阶

Python 正则表达式基础

Python 中的正则表达式是通过 re 模块实现的,它提供了强大的字符串模式匹配功能。下面是正则表达式的基本用法和常见模式:

基本用法

首先需要导入 re 模块:

import re
主要函数
  1. re.match(pattern, string):从字符串的开头匹配模式
  2. re.search(pattern, string):在整个字符串中搜索匹配模式
  3. re.findall(pattern, string):返回所有匹配的子串,以列表形式
  4. re.finditer(pattern, string):返回所有匹配的迭代器
  5. re.sub(pattern, repl, string):替换匹配的子串
  6. re.split(pattern, string):根据匹配的模式分割字符串

常用正则表达式模式

字符匹配
# 匹配单个字符
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']

标志选项

正则表达式函数可以接受标志参数,常用的标志有:

  • re.IGNORECASE 或 re.I:忽略大小写
  • re.MULTILINE 或 re.M:多行模式,影响 ^ 和 $
  • re.DOTALL 或 re.S:点号匹配所有字符,包括换行符
  • re.VERBOSE 或 re.X:允许编写更易读的正则表达式
text = 'Hello\nWorld'
matches = re.findall(r'.+', text, re.DOTALL)
print(matches)  # 输出: ['Hello\nWorld']

这些是 Python 正则表达式的基础知识。正则表达式是一个强大的工具,但也很复杂,建议通过练习和参考官方文档来掌握更多高级用法。


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']

性能优化技巧

  1. 预编译常用模式:对于频繁使用的正则表达式,先编译再使用可以提高性能。

  2. 简化模式:复杂的模式会降低匹配速度,尽量使用简单的模式。

  3. 避免回溯:过多的回溯会导致性能下降,例如嵌套的重复模式。

  4. 使用非贪婪匹配:在不需要贪婪匹配的地方使用非贪婪匹配。

实用示例

提取网页中的所有链接
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 格式(简单版)
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']]

调试工具

正则表达式可能很复杂,调试时可以使用以下工具:

  1. re.DEBUG 标志:显示正则表达式的解析过程
    pattern = re.compile(r'a(b*)c', re.DEBUG)
    
  2. 在线正则表达式测试工具:如 regex101.com, regexr.com 等
  3. 分步构建:先测试简单的部分,再逐步增加复杂度

正则表达式是一个强大但复杂的工具,建议通过练习和实践来掌握这些进阶技巧。对于特别复杂的文本处理任务,也可以考虑结合字符串方法和正则表达式使用,以获得更好的可读性和性能。

你可能感兴趣的:(java,数据库,mysql,python,正则表达式)