基于scrapy的分布式爬虫(3):正则表达式

正则表达式

正则表达式,regular expression,通常被简写为 regex,其作用是对于信息的提取。

  • 基本用法
  • 常见元字符及语法
  • 使用正则表达式编程
  • 练习题
  • 优质学习资源推荐

基本用法

python 中的正则表达式使用不需要安装第三方库,只需要调用re库即可,具体写法为:

import re

subject = "我是一个粉刷匠,粉刷本领强。"
reobj = re.compile(r'.*(粉刷匠).*')
matchobj = reobj.match(subject)
if matchobj:
    print(matchobj.group(1))

# 输出结果
# 粉刷匠

这是一个简单的语句,大家暂时只需要了解就行了。下面将结合例子,讲解正则表达式的内容。


常见元字符及语法

元字符用法说明

12大元字符包括^ $ . * ? + { [ | ( ) \。 注意:不包括 ] - }

这是因为:12大元字符(metacharacters)需要转义字符 / 进行声明,而 ]- 只有在位于一个没有转义的 [ 之后才是元字符,} 不需要转义。

# -*- coding:utf-8 -*-

import re

"""
^: 匹配字符开头
$: 匹配字符结尾
.: 匹配除换行符(\n)之外的任意字符
*: 匹配字符次数(>=0)
?: 非贪婪匹配
+: 匹配字符次数(>=1)
{}: 用来指定匹配次数
[]: 用来表示字符集
|: 表示逻辑"或"
\: 转义字符
"""

## Task1: ^ $ . * 的用法
subject_1 = "woww"

reobj_1_1 = re.compile(r"^w.*w$")
# 匹配以w开头, w结尾的字符串, 中间可以为任意长度字符
print(reobj_1_1.match(subject_1).group())
# 匹配结果为:woww 


## Task2: ?的用法, 关于贪婪匹配和非贪婪匹配
subject_2 = "hahawoooooooooooww"

reobj_2_1 = re.compile(r".*(w.*w).*")
print(reobj_2_1.match(subject_2).group(1))
# 匹配结果为: ww
# 原因: 贪婪匹配时, 前面的 hahawooooooooooo 全部视作 .*
#           此时的执行顺序可以视为从字符串右边开始

reobj_2_2 = re.compile(r".*?(w.*?w).*")
print(reobj_2_2.match(subject_2).group(1))
# 匹配结果为: wooooooooooow
# 原因: 非贪婪匹配时, 执行顺序从左往右
#       ?(w.*?w)的实质为第一个"w....w"形式的字符串


## Task3: {} [] 的用法
# 简单手机号码匹配
# 手机号码特征:长度为11位;
# 常用号段(简单起见, 以前两位为例): 13、15、17、18
subject_3_1 = "12332539403"  # 非手机号码
subject_3_2 = "13902899430"  # 正常手机号码

reobj_3 = re.compile(r"1[3 5 7 8][0-9]{9}")
# 以1开头, 第二位是3 5 7 8, 后面为0-9且共9位
if not reobj_3.match(subject_3_1) and reobj_3.match(subject_3_2):
    print("yes")
# 输出结果: yes


## Task4: () | 的用法
# 判断性别是否正确录入
# 性别只能为"男"或"女"

subject_4_1 = "性别 女"
subject_4_2 = "性别 难"

reobj_4 = re.compile(r"(性别 )(男|女)")
# ()进行分组, | 表示男或女
if reobj_4.match(subject_4_1) and not reobj_4.match(subject_4_2):
    print("yes")
# 输出结果: yes
预定义字符集用法说明
写法含义
\d数字 [0-9]
\D非数字
\s空白字符 [\t \r \n \f \v]
\S非空白字符
\w单词字符 [0-9] [a-z] [A-Z] _(下划线)
\W非单词字符
[\u4E00-\u9FA5]汉字
关于转义字符的一些解释

转义字符 \ 的意义在于,将元字符进行翻译,这里的元字符是指12大元字符。

为了避免操作时出现的混乱,Python 为我们提供了一种简便的写法,即 r""。在该语句中,所有元字符都不需要使用 \ 来说明其意义。

匹配不可打印字符
名称指令16进制
响铃(bell)\a0X07
退出(escape)\e0X1B
换页(form feed)\f0X0C
换行(line feed)\n0X0A
回车(carriage return)\r0X0D
水平制表符(horizontal tab)\t0x09
垂直制表符(vertical tab)\v0x0B
在正则表达式中添加注释

用来解释说明正则表达式含义。方法很简单,只需要在前面添加(?#...) 即可,具体用法如下:

re.compile(r"(?#姓名)(\w+)")

使用正则表达式编程

创建正则表达式对象

re.compile(r".*\d+")

检测是否可以在目标字符串中找到匹配

if re.search("regex pattern", subject):
    # successful match
else:
    # match attempt failed  

检测正则表达式能否匹配整个目标字符串

if re.match(r"regex pattern\Z", subject):
    # \Z 表示定位结束符,定位在末尾,作用同 $
    # successful match
else:
    # match attempt failed

获取匹配文本

matchobj = re.search(r"regex pattern", subject)
if matchobj:
    result = matchobj.group()
else:
    result = ""

确定匹配的位置和长度

matchobj = re.search(r"\d+", subject)
if matchobj:
    matchstart = matchobj.start()
    matchlength = matchobj.end() - matchstart()

命名捕获

matchobj = re.search("http://([a-z0-9.-]+)", subject)
if matchobj:
    result = matchobj.group(1)

Python 支持最多 99 个 group 分组,分组标号从 0 开始。

其中,group(0) 表示整个正则表达式的匹配。

如果想获取包含所有分组所匹配文本的一个元组,调用 groups() 方法。

如果想获取包含所有分组所匹配文本的一个字典,调用 groupdict() 方法。

获取所有匹配的列表

result = re.findall(r"\d+", subject)

遍历全部匹配

for matchobj in re.finditer(r"\d+", subject):
    ......

拆分字符串

result = re.split("<[^<>]*>", subject)

逐行查找

lines = re.split("\r?\n", subject)
reobj = re.compile("regex pattern")
for line in lines[:]:
    if re.search(line):
        # The regex matches line
    else:
        # The regex does not match line

替换掉匹配字符

result = re.sub("before", "after", subject)

练习题

这里给大家出几个练习题,正好巩固一下所学知识。

  1. E-Mail地址合法性验证

    要求:

    1. 以 @ 符号划分,其中 @ 符号之前的为用户名,@ 符号之后的为域名。

    2. 用户名和域名均为常用字符,可以包含一个或多个点号,但是不允许出现两个连续的点号。

    3. 另外,用户名和域名的第一个和最后一个字符不允许为点号。

  2. 传统日期合法性验证

    要求: 日期格式为 mm/dd/yy、mm/dd/yyyy、dd/mm/yy 和 dd/mm/yyyy。

  3. 传统时间格式的合法性验证

    要求: 时间格式为 hh:mm 和 hh:mm:ss,并且要包括 12 小时制和 24 小时制。


优质学习资源推荐

  1. 博客:正则表达式指南。可以作为 cookbook 进行快速查阅,缺点是 python 版本为 2.4。
  2. 知乎:你是如何学会正则表达式的?。内容非常丰富,推荐推荐!
  3. 博客:《构造正则表达式引擎》。建议有一定基础的人再去学习,我暂时只是收藏。
  4. 书籍:《正则表达式经典实例》。本书汇集了 8 种语言的正则表达式内容,非常全面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值