Python 正则表达式常见问题与解决方案
2018-08-08 11:38:24
pattern=re.compile('<span class="glyphicon glyphicon-calendar"></span>(\d+\-\d+\-\d+\s+\d+:\d+:\d+)',re.S)
time_list=re.findall(pattern,response.text)
为啥我这样写匹配不到,我想知道为什么,谢谢
Python 正则表达式常见问题与解决方案
2 回复
正则表达式这块儿确实容易踩坑,我整理几个最常见的场景和对应的解决方案。
1. 贪婪匹配问题 新手最容易遇到的,比如想提取HTML标签里的内容:
import re
# 错误示例 - 贪婪匹配
text = '<div>content1</div><div>content2</div>'
result = re.findall(r'<div>(.*)</div>', text)
print(result) # 输出: ['content1</div><div>content2'] 这不是我们想要的
# 正确做法 - 非贪婪匹配
result = re.findall(r'<div>(.*?)</div>', text)
print(result) # 输出: ['content1', 'content2']
关键点:在量词后面加?变成非贪婪匹配。
2. 匹配多行文本
默认情况下.不匹配换行符:
text = 'first line\nsecond line\nthird line'
# 错误示例
result = re.findall(r'^.*$', text)
print(result) # 只匹配到第一行
# 正确做法 - 使用re.DOTALL或re.S标志
result = re.findall(r'^.*$', text, re.DOTALL)
print(result) # 匹配整个文本
3. 分组捕获的常见误解
text = '2023-01-15'
# 错误理解 - 以为groups()返回所有匹配
pattern = r'(\d{4})-(\d{2})-(\d{2})'
match = re.search(pattern, text)
print(match.groups()) # 输出: ('2023', '01', '15') 这是正确的
# 但findall的行为不同
result = re.findall(pattern, text)
print(result) # 输出: [('2023', '01', '15')] 返回元组列表
4. 特殊字符转义
# 错误示例 - 忘记转义
text = 'price: $100.50'
result = re.search(r'$100', text) # $在正则中是行尾锚点
# 正确做法
result = re.search(r'\$100', text) # 使用\转义
# 或者使用re.escape自动转义
pattern = re.escape('$100') + r'\.\d+'
result = re.search(pattern, text)
5. 性能优化小技巧
# 如果需要多次使用同一个正则,先编译
pattern = re.compile(r'\d{3}-\d{3}-\d{4}')
# 然后重复使用
result1 = pattern.search('phone: 123-456-7890')
result2 = pattern.findall('multiple: 111-222-3333 and 444-555-6666')
6. 常用验证模式
# 邮箱验证(简单版)
email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
# 手机号(中国)
phone_pattern = r'^1[3-9]\d{9}$'
# URL匹配
url_pattern = r'https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+'
7. 替换字符串的高级用法
text = 'John Smith, age 30'
# 使用分组在替换中引用
result = re.sub(r'(\w+)\s+(\w+)', r'\2, \1', text)
print(result) # 输出: Smith, John, age 30
# 使用函数进行复杂替换
def double_age(match):
age = int(match.group(1))
return str(age * 2)
result = re.sub(r'age (\d+)', double_age, text)
print(result) # 输出: John Smith, 60
8. 零宽断言(高级但实用)
text = 'python3 python2 python'
# 正向肯定预查 - 匹配后面跟着数字的python
result = re.findall(r'python(?=\d)', text)
print(result) # 输出: ['python', 'python']
# 正向否定预查 - 匹配后面不跟数字的python
result = re.findall(r'python(?!\d)', text)
print(result) # 输出: ['python']
总结建议:多测试,善用regex101这类在线工具验证你的表达式。
你要匹配的数据呢 只丢个表达式出来谁能看出问题?

