python正则表达式与re模块-02
正则表达式
正则表达式与python的联系
# 正则表达式不是Python独有的,它是一门独立的技术,所有的编程语言都可以使用正则
# 但要在python中使用正则表达式,就必须依赖于python内置的re 模块
验证手机号是否合法的小案例
phone_number = input('please input your phone number : ')
if len(phone_number) == 11 \
and phone_number.isdigit() \
and (phone_number.startswith('') \
or phone_number.startswith('') \
or phone_number.startswith('') \
or phone_number.startswith('') \
or phone_number.startswith('')):
print('是合法的手机号码')
else:
print('不是合法的手机号码')
纯使用python代码版
import re
phone_number = input('please input your phone number : ')
if re.match('^(13|14|15|18|19)[0-9]{9}$', phone_number):
print('是合法的手机号码')
else:
print('不是合法的手机号码')
python代码结合正则表达式版
从上面两段代码中很容易就可以看得出来,使用正则表达式来校验手机号明显要比纯python 代码验证来的精简得多。
下面就正式介绍一下正则表达式的一些基本知识
正则表达式
正则表达式: # 一种匹配字符串的规则
官方定义: # 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
常见的应用场景: # 爬虫 , # 数据分析 , # 各种数据校验(身份证号、手机号...)
如果你想系统的学习,可以去了解一下《正则指引》这本书
在开始讲正则语法之前,先推荐大家一个验证正则的网站,可以在线测试你的正则表达式能否满足你的预期效果:【正则表达式在线测试】 ,大家可以边学习边在该网站上面验证
你改变正则表达式或者下方的待处理字符串他会自动重新匹配
字符组
# 在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示
常见的字符组(一个字符组中的数据都是 '或' 的关系)
注意: # 字符组可以用 '-' 表示范围,左右两边要按照ASCII码表的顺序书写,可以 0-9 不可以 9-0,9的ASCII值比0大
字符
常见元字符(推荐按不同颜色来分组记)
注意: # ^ 与 & 会精准限制匹配的内容,两者中间写什么,待匹配的字符串就必须是什么,多一个少一个都不行 , # 运用 | (“或”)的时候一定要把长的写在前面,否则匹配到短的就匹配完成了,会有很多被截断的
分组(): # 当多个正则符号需要重复多次的时候,或者当做一个整体,进行其他操作,那么可以用分组的形式,分组在正则的语法中就是一个小括号 '(表达式)' ,里面放表达式即可
转义字符
观察上面的元字符可以发现其中有 \n \t 等代表特殊含义的元字符,如果就是要匹配一个字符串 '\n',则会与元字符冲突,故需要在 '\' 前面再加上一个 '\',来防止转义,即要表示字符串 '\n' 正则中需要写成 '\\n'
量词
只能跟在元字符/字符组/正则组后面,限制其左边紧挨着的那个正则表达式(元字符/字符组/正则组),不可两个量词连在一起(除了 '?',用来解除正则的贪婪模式)
*、+、? 推荐如图所示的画坐标系的方式记忆
贪婪匹配与非贪婪匹配(惰性匹配)
贪婪匹配: # 在满足匹配时,匹配尽可能长的字符串
非贪婪匹配: # 在满足匹配时,匹配尽可能短的字符串
python的匹配模式默认为贪婪匹配,在量词后面加上 ? 可以将其匹配模式改为非贪婪模式,会匹配尽量少的字符串(仅量词作用的那个对象会受影响)
贪婪匹配原理个人理解: # 先匹配到目标字符串 '<',然后直接读取到后面所有的字符串,从倒数第一个字符开始往回找,找到 '>',则将前面的那个位置至这个位置之间的数据返回 ,注意这里是 .* 任意字符 无限多次!!!
非贪婪原理个人理解: # 先匹配到目标字符串 '<',从该位置开始往后寻找字符 '>',找到则这对数据为一个匹配返回结果 ,注意这里是 .* 任意字符 无限多次!!!
案例练习
推荐案例 【正则表达式练习题】 ,可以根据案例巩固知识
如果你看了本文觉得描述不清,可以参考 【re模块 】这篇博客,亦或是下图的出处的博客 【python正则表达式指南】 (前者的博客页面排版看着美观一些,但大部分数据均来源于后者)
python 中的re模块
上面只是介绍了正则表达式的一些基础知识,它是一门独立的技术,要想在python中使用正则表达式,自然就需要通过学习python内置的re模块了(也可以通过其他的一些函数方法等方式使用正则)
要使用 re模块,请不要忘记先导模块( import re )
本文此部分的参考性可能不高,内容也不是很全面,仅作为个人小结,如果有兴趣可以参考 【re模块】 里面有更详细的讲解以及丰富的案例(另:本模块知识很少用到,所以仅做笔记翻阅)
常见重点函数 findall、search、match
findall 找出字符串所有符合内容成一个列表 search 查找匹配结果 match 从开头开始比对
import re '''
findall 所有符合正则表达式的所有内容
search 有没有符合正则表达式的内容
match 是不是正则表达式对应的开头
'''
# findall 找出字符串中符合正则表达式的所有内容,并且返回一个列表,列表中的元素就是正则表达式匹配到的结果
res = re.findall('[a-z]+', 'nice toZmeet you') # 匹配任意多个小写字母(一个及以上),空格、大写字母,均不符合要求
print(res)
# ['nice', 'to', 'meet', 'you'] # search 不会直接返回匹配到的结果,而是给你返回一个对象,这个对象需要调用,通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
# 注意:1.search 只会依据正则查找一次,只要查到了结果,就不会往后查找了
# 2.当查找的结果不存在的情况下,调用group会直接报错
res = re.search('ou', 'nice toZmeet you')
res2 = res.group() # 必须调用group 才能看到匹配到的结果
print(res, res2)
# <_sre.SRE_Match object; span=(14, 16), match='ou'> ou
res1 = re.search(r'\.', 'nice toZmeet you') # 匹配字符串中是否有 . 这个字符
print(res1)
# None
# print(res1.group()) # 直接报错,可先判断 res1 是不是 None,再进行取值 # match
# 注意:1.match 只会匹配字符串的开头部分
# 2.当字符串的开头与正则表达式不符合匹配规则的情况下,返回的也是None,调用 .group 也会报错
res = re.match('s', 'sda e rf a f')
print(res)
# <_sre.SRE_Match object; span=(0, 1), match='s'>
print(res.group())
# s res = re.match('a', 'sda e rf a f')
print(res)
# None
# print(res.group()) # 直接报错,'NoneType' object has no attribute 'group' '''
正则表达式,返回类型为表达式对象的,如:<_sre.SRE_Match object; span=(6, 7), match='a'>,返回对象时,需要用正则方法取字符串,方法有:
.group() # 获取匹配到的所有结果,不管有没有分组将匹配到的全部拿出来,有参取匹配到的第几个如2
.groups() # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分的结果
.groupdict() # 获取模型中匹配到的分组结果,只拿出匹配到的字符串中分组部分定义了key的组结果
'''
重点掌握findall search match
不常用函数 split、sub、compile、finditer
split 切割 sub 替换 compile 将正则编译成一个对象,可对象. 调用上述方法 finditer 返回一个放返回结果的迭代器
import re # split 类似于字符串的切割split,返回一个列表(他会把被替换掉的字符变成空格)
res = re.split('[ab]', 'sabcasbdsafafabfas')
print(res)
# ['s', '', 'c', 's', 'ds', 'f', 'f', '', 'f', 's'] # sub 类似于字符串的replace 方法,返回替换完成的字符串,可指定替换次数
# sub('正则表达式', '新的内容', '带匹配的字符串', [要替换的次数])
# 先按正则表达式查找所有符合该表达式的内容,统一替换成'新的内容',还可以通过n来控制替换的个数
ret = re.sub('\d', 'H', 'eva3egon4yuan4', 1) # 将数字替换成'H',参数1表示只替换1个
print(ret)
# evaHegon4yuan4 # subn() 字符串replace的加强版,返回替换完成的字符串与总共替换的次数(封成了一个元组)
# 返回的是一个元组,元组的第一个元素是替换完成后的结果,第二个元素代表的是替换的个数
ret = re.subn('\d', 'H', 'eva3egon4yuan4') # 将数字替换成'H',返回元组(替换的结果,替换了多少次)
print(ret)
# ('evaHegonHyuanH', 3) # compile 将正则编译成一个对象,后期可以直接用它来调用 findall、search 等方法
obj = re.compile('\d{3}') # 将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') # 正则表达式对象调用search,参数为待匹配的字符串
print(ret.group())
# # finditer 返回一个存放匹配结果的迭代器,可以使用前面学习到的 迭代器对象.__next__() 方法调用 ---> 简写 next(迭代器对象)
ret = re.finditer('\d', 'ds3sy4784a')
print(ret)
# <callable_iterator object at 0x000001AE62617160>
print(next(ret).group()) # 查看第一个结果
#
print(next(ret).group()) # 查看第二个结果
#
print([i.group() for i in ret]) # 查看剩余的左右结果
# ['7', '8', '4']
其他非重点 split sub subn complie finditer
扩展
各方法分组的区别
import re # search与match均支持获取分组内容的操作 跟正则无关,是python机制
res = re.search('^[1-9]\d{14}(\d{2}[0-9x])?$', '')
print(res.group())
#
print(res.group(1)) # 获取正则表达式括号阔起来分组的内容(最后三位是:两个数字 加上 0-9或者x)
#
# print(res.group(2)) # 报错:IndexError: no such group ,取不到 # 而针对findall它没有group取值的方法,所以它默认就是分组优先获取的结果
ret = re.findall('www.(baidu|google).com', 'www.google.com')
print(ret) # 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消分组优先即可
# ['google'] ret = re.findall('www.(?:baidu|google).com', 'www.google.com') # ?:取消分组优先
print(ret)
# ['www.google.com']
分组优先机制
import re ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>", "<h1>hello</h1>")
# 还可以在分组中利用 ?<name> 的形式给分组起名字
# 获取的匹配结果可以直接用 .group('名字') 拿到对应的值
print(ret.group('tag_name'))
# h1
print(ret.group())
# <h1>hello</h1>
"""
注意 ?P=tag_name 相当于引用之前正则表达式,并且匹配到的值必须和前面的正则表达式一模一样
""" # 案例
# 匹配字符串中的所有数字
ret = re.findall(r"\d+", "1-2*(60+(-40.35/5)-(-4*3))")
print(ret)
# ['1', '2', '60', '40', '35', '5', '4', '3'] # 匹配字符串中的所有整数
ret = re.findall(r"\d+\.\d*|(\d+)", "1-2*(60+(-40.35/5)-(-4*3))")
print(ret)
# ['1', '2', '60', '', '5', '4', '3']
ret.remove("")
print(ret)
# ['1', '2', '60', '5', '4', '3']
分组取别名取值
爬虫小案例
'''
本爬虫案例思路:
分析 https://movie.douban.com/top250?start=%0&filter= 页面得知,每页有25条数据
通过分次请求该地址,将返回的HTML代码通过正则匹配,解析成想要的字符串格式,
分页分条存入文件中去(用到了 分组 和 取别名 的知识点)
'''
import re
from urllib.request import urlopen def getPage(url):
response = urlopen(url)
return response.read().decode('utf-8') def parsePage(s):
com = re.compile(
'<div class="item">.*?<div class="pic">.*?<em .*?>(?P<id>\d+).*?<span class="title">(?P<title>.*?)</span>'
'.*?<span class="rating_num" .*?>(?P<rating_num>.*?)</span>.*?<span>(?P<comment_num>.*?)评价</span>', re.S) ret = com.finditer(s)
for i in ret:
yield {
"id": i.group("id"),
"title": i.group("title"),
"rating_num": i.group("rating_num"),
"comment_num": i.group("comment_num"),
} def main(num):
url = 'https://movie.douban.com/top250?start=%s&filter=' % num
response_html = getPage(url)
ret = parsePage(response_html)
print(ret)
f = open("move_info7.txt", "a", encoding="utf8") for obj in ret:
print(obj)
data = str(obj)
f.write(data + "\n") count = 0
for i in range(10):
main(count)
count += 25
爬取豆瓣电影Top250小案例
数据小样
上面仅仅只是一个简单的爬虫案例,如果你想成为一名爬虫工程师,那么你必须的能够熟练地写出正则表达式,言下之意就是除了本文的内容,你还需要好好去学学正则表达式的内容
python正则表达式与re模块-02的更多相关文章
- python正则表达式之re模块方法介绍
python正则表达式之re模块其他方法 1:search(pattern,string,flags=0) 在一个字符串中查找匹配 2:findall(pattern,string,flags=0) ...
- python 正则表达式 (重点) re模块
京东的注册页面,打开页面我们就看到这些要求输入个人信息的提示.假如我们随意的在手机号码这一栏输入一个11111111111,它会提示我们格式有误.这个功能是怎么实现的呢?假如现在你用python写一段 ...
- Python正则表达式与re模块介绍
Python中通过re模块实现了正则表达式的功能.re模块提供了一些根据正则表达式进行查找.替换.分隔字符串的函数.本文主要介绍正则表达式先关内容以及re模块中常用的函数和函数常用场景. 正则表达式基 ...
- Python正则表达式与hashlib模块
菜鸟学python第十六天 1.re模块(正则表达式) 什么是正则表达式 正则表达式是一个由特殊字符组成的序列,他能帮助对字符串的某种对应模式进行查找. 在python中,re 模块使其拥有全部的正则 ...
- python 正则表达式re使用模块(match()、search()和compile())
摘录 python核心编程 python的re模块允许多线程共享一个已编译的正则表达式对象,也支持命名子组.下表是常见的正则表达式属性: 函数/方法 描述 仅仅是re模块函数 compile(patt ...
- Python正则表达式与re模块
在线正则表达式测试 http://tool.oschina.net/regex/ 常见匹配模式 模式 描述 \w 匹配字母数字及下划线 \W 匹配非字母数字下划线 \s 匹配任意空白字符,等价于 [\ ...
- python 正则表达式与re模块
一.正则表达式 用途 用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. #### 简单地说 就是用于字符串匹配的 字符组 在 ...
- Python 正则表达式、re模块
一.正则表达式 对字符串的操作的需求几乎无处不在,比如网站注册时输入的手机号.邮箱判断是否合法.虽然可以使用python中的字符串内置函数,但是操作起来非常麻烦,代码冗余不利于重复使用. 正则表达式是 ...
- [ python ] 正则表达式及re模块
正则表达式 正则表达式描述: 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个‘规则字符串’,这个‘规则字符串’用来 表达对字符串的一种过滤 ...
随机推荐
- 使用 acl_cpp 的 HttpServlet 类及服务器框架编写WEB服务器程序(系列文章)
在 <用C++实现类似于JAVA HttpServlet 的编程接口 > 文章中讲了如何用 HttpServlet 等相关类编写 CGI 程序,于是有网友提出了 CGI 程序低效性,不错, ...
- Ubuntu 下压缩软件的安装
在ubuntu下,系统就自带一个压缩包管理软件,但是,它默认是不支持rar和7zip格式的.因此,我们可以给它直接“增强”一下.就成了万能的了.安装方法,终端里面: sudo apt-get inst ...
- play框架之简介
Play Framework是一个开源的Web框架,背后商业公司是Typesafe.要介绍Play之前,首先理清Play的两个不同的分支. Play 1.x 使用Java开发,最新版本是1.3.1,只 ...
- TCP使用注意事项总结
目录 发送或者接受数据过程中对端可能发生的情况汇总 本端TCP发送数据时对端进程已经崩溃 本端TCP发送数据时对端主机已经崩溃 本端TCP发送数据时对端主机已经关机 某个连接长时间没有数据流动 TCP ...
- 请给出linux中查看系统已经登录用户的命令?
w命令 第一行:当前系统运行了多久和系统负载 谁正在远程登录系统并且在干什么 [root@martin ~]# w 11:30:33 up 4 days, 18:10, 2 users, load a ...
- 网关never_host设计
never下app的host与api Never是纯c#语言开发的一个框架.host则是使用该框架开发出来的API网关,它包括了:路由.认证.鉴权.熔断,内置了负载均衡器Deployment:并且只需 ...
- 纯CSS制作加<div>制作动画版哆啦A梦
纯CSS代码加上<div>制作动画版哆啦A梦(机器猫) 哆啦A梦(机器猫)我们大家一定都很熟悉,今天给大家演示怎么用纯CSS代码,来做一个动画版的哆啦A梦. 效果图: ###下面代码同学可 ...
- Angular中input和output使用
// 写法一: 1 @Components({ 2 ...., 3 inputs:['init'], 4 outputs:['finish'] 5 }) 6 export class xxx(){ 7 ...
- python的is与==的区别
is is比较的是两个变量的地址值,如果地址值正确,则返回True,否则返回False,实例如下: 如图所示,a,b列表的数值相等,但地址是不相等的,所以返回True,与值无关 == ==比较的是两个 ...
- oraclesql遇见的问题(一)
在oracle的数据库,对于字段为null的字段过滤条件只能用is null 或者 is not null,不能使用 != , <> , = 判断, 今天进行接口测试时,发现获取到的数据缺 ...