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这类在线工具验证你的表达式。


你要匹配的数据呢 只丢个表达式出来谁能看出问题?

回到顶部