Python 正则表达式全面指南

正则表达式是处理字符串的强大工具,在爬虫开发中用于从 HTML 代码中提取信息尤为有效。本文将全面介绍 Python 中正则表达式的使用方法。

1. 正则表达式基础

1.1 什么是正则表达式

正则表达式(Regular Expression)是一种用于匹配字符串中字符组合的模式。它有自己的特定语法结构,可以实现字符串的检索、替换、匹配验证等功能。

1.2 在线测试工具

可以使用开源中国提供的正则表达式测试工具进行测试:

我的电话号码是:13812345678,邮箱是:example@domain.com,个人网站:https://www.example.com
  • 匹配 Email 地址:\w+@\w+\.\w+
  • 匹配 URL:https?://[^\s]+

2. Python re 模块

Python 通过 re 模块提供正则表达式功能,常用方法包括:

方法描述
re.match()从字符串开头匹配
re.search()扫描整个字符串匹配
re.findall()返回所有匹配结果
re.sub()替换匹配内容
re.compile()编译正则表达式对象

3. 常用匹配方法

3.1 match 方法

match() 从字符串开头匹配,成功返回匹配对象,失败返回 None。

import re

content = 'Hello 123 4567 World_This'
pattern = '^Hello\s\d{3}\s\d{4}\s\w{10}'
result = re.match(pattern, content)
print(result.group())  # Hello 123 4567 World_This
print(result.span())   # (0, 25)

分组匹配

使用 () 进行分组提取:

content = 'Hello 1234567 World_This'
pattern = '^Hello\s(\d+)\sWorld'
result = re.match(pattern, content)
print(result.group(1))  # 1234567

3.2 search 方法

search() 扫描整个字符串并返回第一个匹配:

content = 'Extra Hello 1234567 World_This'
pattern = 'Hello\s(\d+)\sWorld'
result = re.search(pattern, content)
print(result.group(1))  # 1234567

3.3 findall 方法

findall() 返回所有匹配结果:

html = '''
<ul>
    <li><a href="https://www.example1.com">Example1</a></li>
    <li><a href="https://www.example2.com">Example2</a></li>
</ul>
'''
pattern = '<li><a href="(.*?)">(.*?)</a></li>'
results = re.findall(pattern, html, re.S)
for result in results:
    print(result[0], result[1])

4. 高级匹配技巧

4.1 贪婪与非贪婪匹配

  • 贪婪匹配:.*(尽可能多匹配)
  • 非贪婪匹配:.*?(尽可能少匹配)
content = 'Hello 1234567 World_This'
pattern = '^He.*(\d+).*Demo$'      # 贪婪匹配,只匹配到7
pattern = '^He.*?(\d+).*Demo$'     # 非贪婪匹配,匹配到1234567

4.2 修饰符

修饰符描述
re.I忽略大小写
re.S使 . 匹配包括换行符
re.M多行模式
re.X忽略空白和注释
content = '''Hello 1234567 
World_This'''
pattern = '^He.*?(\d+).*?This$'
result = re.search(pattern, content, re.S)

4.3 转义匹配

对特殊字符使用 \ 进行转义:

content = '(百度)www.baidu.com'
pattern = '\(百度\)www\.baidu\.com'
result = re.search(pattern, content)

5. 实用方法

5.1 sub 替换

content = '54aK54yr5oiR54ix5L2g'
result = re.sub('\d+', '', content)  # aKyroiRixLg

5.2 compile 预编译

pattern = re.compile('\d{2}:\d{2}')
content1 = '12:34'
content2 = '23:45'
result1 = pattern.search(content1)
result2 = pattern.search(content2)

6. 常用匹配模式总结

模式描述
.匹配任意字符(除换行符)
\w匹配字母/数字/下划线
\s匹配空白字符
\d匹配数字
^匹配字符串开头
$匹配字符串结尾
*匹配0次或多次
+匹配1次或多次
?匹配0次或1次
{n}匹配n次
{n,}匹配至少n次
{n,m}匹配n到m次
[abc]匹配a或b或c
[^abc]匹配非a且非b且非c

7. 实际应用示例

7.1 提取HTML内容

html = '''
<div class="song">
    <p>歌手:周杰伦</p>
    <p>歌曲:七里香</p>
</div>
'''
pattern = '<p>歌手:(.*?)</p>.*?<p>歌曲:(.*?)</p>'
result = re.search(pattern, html, re.S)
if result:
    print(result.group(1), result.group(2))  # 周杰伦 七里香

7.2 验证字符串格式

# 验证邮箱
def is_valid_email(email):
    pattern = '^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$'
    return re.match(pattern, email) is not None

8. 性能优化建议

  1. 尽量使用非贪婪匹配 .*?
  2. 复杂正则表达式使用 re.compile() 预编译
  3. 合理使用修饰符,如 re.Sre.I
  4. 避免过度使用回溯,可能导致性能问题

正则表达式是爬虫开发中不可或缺的工具,掌握它可以高效地从HTML中提取所需信息。建议多加练习,熟悉各种匹配模式的使用场景。