您的位置:首页 > 其它

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

2018-03-16 17:08 162 查看

正则表达式

正则表达式,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)


练习题

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

E-Mail地址合法性验证

要求:

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

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

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

传统日期合法性验证

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

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

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

优质学习资源推荐

博客:正则表达式指南。可以作为 cookbook 进行快速查阅,缺点是 python 版本为 2.4。

知乎:你是如何学会正则表达式的?。内容非常丰富,推荐推荐!

博客:《构造正则表达式引擎》。建议有一定基础的人再去学习,我暂时只是收藏。

书籍:《正则表达式经典实例》。本书汇集了 8 种语言的正则表达式内容,非常全面。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  正则表达式