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模块
正则表达式 正则表达式描述: 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个‘规则字符串’,这个‘规则字符串’用来 表达对字符串的一种过滤 ...
随机推荐
- 修改Maven的本地仓库地址
已经配置好的设定文件: 1.创建一个本地仓库的地址 2.修改Maven中conf目录下的settings.xml文件 在此处添加修改后的本地仓库的地址 3.打开cmd 输入mvn help:sys ...
- qt源码的submodules要怎么使用
请问我下载了submodules里面的源代码,怎么使用?http://download.qt.io/official_releases/qt/5.7/5.7.1/submodules/如下载了qweb ...
- FMXUI中的三大杀器:TView、TLinearLayout、TRelativeLayout
好了,今天我们来介绍下FMXUI中的三大杀器:TView.TLinearLayout.TRelativeLayout. [名词定义] 非布局组件: 组件名不是以Layout结尾的组件,Delphi自带 ...
- windows Service 之调试过程(附加到进程里调试,而且启动时间不能超过30秒)
最近第一次用C#写了一个windows service ,其实实现的内容比较简单.就是启动remoting 连接,但是调试相对初次写windws service 的我来说,比较烦.没有经验,而且没办法 ...
- qt 自动重启(两种方法)
所谓自动重启就是程序自动关闭后在重新打开: 一般一个qt程序main函数如下: int main(int argc, char* argv[]) { QApplication app(argc, ar ...
- 凤年读史27:普鲁士vs德意志
孙宇 普鲁士,是熟悉历史的人都知道的一个名词,它与德国关系密切.似乎在某些情境中,普鲁士就是德国,而在另一些场合,普鲁士和德国又不一样,有所区别.那么普鲁士到底是什么?它和德国到底是什么关系? 普鲁士 ...
- Java 诞生的趣事
Java 命名的由来 Java是印度尼西亚爪哇岛的英文名称,因盛产咖啡而闻名.Java语言中的许多库类名称,多与咖啡有关:如JavaBeans(咖啡豆).NetBeans(网络豆)以及Object ...
- Android WebView设置背景透明
Adndroid 2.x的设置 在Android 2.x下,设置webview背景为透明的方法: wvContent.setBackgroundColor(0); Adndroid 4.0 由于硬件加 ...
- 一线Python运维开发带你秒懂Flask框架
相信曾经纠结过这个问题:怎样才能彻底掌握flask? Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 . ...
- 【HDU - 2612】Find a way
-->Find a way 直接上Chinese Descriptions: hsj和lsh最近迷上了pokemon go的游戏.在双十一大物期中考试来临之前,他们想抓一只稀有土拨鼠来攒攒人品 ...