第三章:正则表达式——乱码中找对象的“神技”

上一章的requests库是一个常用的 HTTP 请求库,可以方便地向网站发送 HTTP 请求,并获取响应结果。爬虫就是解析网页的内容将需要的信息爬取出来,本章节学习正则表达式的内容,正则表达式可以精准将需要的内容从整体中提取出来

目标:掌握正则表达式,让混乱的文本秒变“结构化数据”,从此告别“肉眼找规律”的苦逼生活!
学习目标:学会用正则匹配手机号、邮箱、身份证号,甚至“从一堆乱码中精准提取小姐姐的微信号”(开玩笑的,请遵纪守法)。


3.1 为什么学正则表达式?

(温馨提示:如果你觉得写字符串处理代码像“便秘”,学完本章你会“畅快淋漓”)

正则表达式的三大优势:

  1. 万能文本捕手:从杂乱无章的文本中提取关键信息(比如从一篇3000字的文章里揪出所有日期)
  2. 一行代码顶百行:用正则替换循环+判断(比如批量删除文件名中的空格)
  3. 江湖必备技能:面试常考、爬虫必备、数据处理神器

代码对比:普通方法 vs 正则

 

python

# 普通方法(假设要从字符串中提取所有数字)
text = "我的电话是123456,另一个是789012"
numbers = []
for i in range(len(text)):
    if text[i].isdigit():
        num = ""
        while i < len(text) and text[i].isdigit():
            num += text[i]
            i += 1
        numbers.append(num)
print(numbers)  # ['123456', '789012'](写得我手都酸了)

# 正则方法(一行搞定):
import re
numbers = re.findall(r"\d+", text)
print(numbers)  # ['123456', '789012'](正则:这都不是事儿)

3.2 正则基础语法:从“小白”到“入门”

元字符速记表(附搞笑注释)

符号作用举个栗子(匹配手机号)
.匹配任意字符(除了换行符)1.5 可以匹配 1a5135 等
\d匹配数字(等价于[0-9])\d{11} → 匹配11位数字(手机号)
\w匹配字母/数字/下划线\w+ → 匹配类似user_123的用户名
*前一个字符出现0次或多次ab*c → 匹配acabcabbbc
+前一个字符出现1次或多次ab+c → 匹配abcabbbc,但不匹配ac
?前一个字符出现0次或1次colou?r → 匹配colorcolour
{n,m}前一个字符出现n到m次\d{3,4} → 匹配3到4位数字(区号)
``或关系(二选一)
^匹配字符串开头^Hello → 匹配以Hello开头的字符串
$匹配字符串结尾\d+$ → 匹配以数字结尾的字符串

代码示例:手机号匹配

 

python

import re

text = "联系我:手机13812345678,座机010-12345678"
pattern = r"1[3-9]\d{9}"  # 手机号正则(国内11位)

# findall返回所有匹配结果
phones = re.findall(pattern, text)
print(phones)  # ['13812345678']

# match从字符串开头匹配(如果手机号不在开头会匹配失败)
result = re.match(pattern, text)
print(result)  # None(因为前面有“联系我:手机”)

3.3 常用函数:正则的“三板斧”

1. re.findall():暴力搜索所有匹配项

 

python

# 提取所有邮箱地址
text = "我的邮箱是a@b.com,备用邮箱c.d@e.co.uk"
emails = re.findall(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", text)
print(emails)  # ['a@b.com', 'c.d@e.co.uk']

2. re.search():找到第一个匹配项

 

python

# 提取第一个日期
text = "会议时间:2023-10-01,截止日期:2023-12-31"
date_pattern = r"\d{4}-\d{2}-\d{2}"
first_date = re.search(date_pattern, text).group()
print(first_date)  # '2023-10-01'

3. re.sub():文本替换神器

 

python

# 把所有空格替换成下划线(即使中间有多个空格)
text = "Hello   World    Python"
new_text = re.sub(r"\s+", "_", text)
print(new_text)  # "Hello_World_Python"

4. re.split():按规则分割字符串

 

python

# 按非数字字符分割字符串
text = "abc123def456ghi"
parts = re.split(r"\D+", text)  # \D+ 匹配一个或多个非数字
print(parts)  # ['abc', '123', 'def', '456', 'ghi']

3.4 分组捕获:正则的“抓重点”技能

分组语法:用小括号()标记分组

 

python

# 提取日期中的年月日
text = "日期:2023-10-01"
pattern = r"(\d{4})-(\d{2})-(\d{2})"
match = re.search(pattern, text)
if match:
    year, month, day = match.groups()
    print(f"年:{year}, 月:{month}, 日:{day}")  # 年:2023, 月:10, 日:01

命名分组:给分组起个名字(方便后期调用)

 

python

pattern = r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})"
match = re.search(pattern, text)
if match:
    print(match.group("year"))  # 2023

3.5 贪婪与非贪婪模式:正则的“选择困难症”

贪婪模式(默认):尽可能多匹配

 

python

text = "<div>内容1</div><div>内容2</div>"
pattern = r"<div>(.*)</div>"
result = re.search(pattern, text)
print(result.group(1))  # "内容1</div><div>内容2"(匹配到最后一个</div>)

非贪婪模式:尽可能少匹配(加?

 

python

pattern = r"<div>(.*?)</div>"
result = re.findall(pattern, text)
print(result)  # ['内容1', '内容2'](精准匹配每个div内容)

3.6 高级技巧:正则的“超能力”

1. 零宽断言:匹配位置而非内容

 

python

# 匹配后面跟着“元”的数字(比如价格后面的金额)
text = "价格:99元,原价:199元"
pattern = r"\d+(?=元)"  # (?=元) 表示后面必须是“元”
print(re.findall(pattern, text))  # ['99', '199']

2. 编译正则表达式:提升效率

 

python

import re

pattern = re.compile(r"\d+")  # 预编译正则表达式
numbers = pattern.findall("a1b22c333")
print(numbers)  # ['1', '22', '333']

3. 处理复杂文本:邮箱去重

 

python

text = "联系我:a@a.com, b@b.com, a@a.com"
emails = list(set(re.findall(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", text)))
print(emails)  # ['b@b.com', 'a@a.com']

3.7 错误处理:正则的“防崩溃”指南

 

python

try:
    re.compile("]invalid[regex")  # 故意写一个错误正则
except re.error as e:
    print(f"正则语法错误:{e}")  # 正则语法错误:nothing to repeat at position 0

3.8 学习渠道推荐:成为正则大师的捷径

  1. 在线练习

    • Regex101(实时调试+中文解释)
    • 菜鸟教程正则表达式(中文入门宝典)
  2. 书籍推荐

    • 《精通正则表达式》(俗称“圣经”,看完能装逼)
    • 《Python正则表达式操作指南》(实战派首选)
  3. 避坑指南

    • 避免过度使用贪婪模式(否则会匹配到奇怪的内容)
    • re.VERBOSE写多行正则(加注释更清晰)
       

      python

      pattern = re.compile(r"""
          \d{4}       # 年份4位数字
          -           # 分隔符
          \d{2}       # 月份2位数字
          -           # 分隔符
          \d{2}       # 日期2位数字
      """, re.VERBOSE)

3.9 本章小结

  • 核心技能

    1. 掌握元字符、分组、贪婪模式等基础语法
    2. 熟练使用findallsearchsub等函数
    3. 能用正则解决实际问题(如数据清洗、日志分析)
  • 避坑指南

    • 正则写完后先用简单文本测试(避免线上翻车)
    • 复杂正则建议拆解成多步骤处理(比如先提取再处理)

正则表达式的搞笑彩蛋
如果正则表达式会说话,可能会吐槽:“人类总让我干脏活累活,却不知道我内心在咆哮:‘这字符串是外星文明写的吗?!’”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值