今天要学会正则表达式。使用菜鸟教程的正则表达式教程,主要使用python正则表达式函数进行学习。
正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a到z之间的字母)和特殊字符(称为”元字符”)。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
简介
我们很可能使用 ? 和 通配符来查找硬盘上的文件。? 通配符匹配文件名中的 0 个或 1 个字符,而 通配符匹配零个或多个字符。像 “data(\w)?.dat” 这样的模式将查找下列文件:1
2
3
4
5data.dat
data1.dat
data2.dat
datax.dat
dataN.dat
使用 字符代替 ? 字符扩大了找到文件的数量,即”data.\.data”。* 即通配符。1
2
3
4
5
6data.dat
data1.dat
data2.dat
data12.dat
datax.dat
dataXYZ.dat
简单实例: ^[0-9]+abc$,其含义是:
- ^为匹配输入字符串的开始位置
- [0-9]+匹配多个数字,[0-9]匹配单个数字,+匹配一个或者多个
- abc$匹配字符abc并以abc结尾,$为匹配输入字符串的结束位置。
我们在写用户注册表时,只允许用户名包含字符、数字、下划线和连接字符(-),并设置用户名长度,可以用以下正则表达式设定: ^[a-z0-9_-]{3,15}$
为什么使用正则表达式?
通过使用正则表达式,可以:
- 测试字符串内的模式。例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。
- 替换文本。可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。
- 基于模式匹配从字符串中提取子字符串。可以查找文档内或输入域内特定的文本。
python正则表达式
re模块使python语言拥有全部的正则表达式功能。
re.match函数
re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。函数语法:re.match(pattern, string, flags=0)。
- pattern: 匹配的正则表达式
- string: 要匹配的字符串
- flags: 标志位,用于控制正则表达式的匹配方式
我们可以使用group(num)或groups()匹配对象函数来获取匹配表达式。
- group(num=0): 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
- groups(): 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
例子:
其中span()函数span() 返回一个元组包含匹配 (开始,结束) 的位置。
前面的一个r表示字符串为非转义的原始字符串,让编译器忽略反斜杠,也就是忽略转义字符。但是这个字符串里没有反斜杠,所以这个r可有可无。 (.*) 第一个匹配分组,.*代表匹配除换行符之外的所有字符;(.*?)第二个匹配分组,.*?后面多个问号,代表非贪婪模式,也就是说只匹配符合条件的最少字符;后面的一个.* 没有括号包围,所以不是分组,匹配效果和第一个一样,但是不计入匹配结果中。
re.search函数
re.search 扫描整个字符串并返回第一个成功的匹配。函数语法:re.search(pattern, string, flags=0),参数含义与match函数的相同。
例子:
re.match与re.search的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
检索与替换
Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。语法:re.sub(pattern, repl, string, count=0, flags=0)。参数:
- pattern : 正则中的模式字符串。
- repl : 替换的字符串,也可为一个函数。
- string : 要被查找替换的原始字符串。
- count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
例子:
repl参数一个函数
下面例子将字符串中的匹配的数字乘以2:
记住要加?号,否则没有命名成功为group:
re.compile函数
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
语法格式为:re.compile(pattern[, flags])
参数:
- pattern : 一个字符串形式的正则表达式
- flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:
- re.I 忽略大小写
- re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
- re.M 多行模式
- re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
- re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
- re.X 为了增加可读性,忽略空格和 # 后面的注释
re.findall函数
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。语法格式为:findall(string, pos, endpos)
时间关系,其他知识今后再学习
任务
结合requests、re两者的内容爬取 https://movie.douban.com/top250 中的内容,要求抓取名次、影片名称、国家、导演等字段。
1 | import requests |
过程中遇到的问题:
- 本来是不打算加请求头,但是在查找资料时发现不加请求头可能会被阻止(其实不加好像也可以爬取)
- 爬取的数据我使用csv存储
- 过程中需要用到中文匹配的知识,一开始没什么头绪,后来查找博客发现使用[\u4e00-\u9fa5]代表中文字符
- 一开始只能抓到前20多部电影,后来经群里的同学提示,可以通过for循环来跨页爬取。
内容显示如下: