Python的re模块,正则表达式书写方法
Python的re模块,正则表达式
#导入re模块
import re
1、match方法的使用:
result = re.match(正则表达式,待匹配的字符串)
正则表达式写法:
第一部分:
字符 |
功能 |
.(点,英文的句号) |
匹配任意一个字符,除了\n |
[] |
匹配[]中列举的字符 |
\d |
匹配数字,即0-9 |
\D |
匹配非数字 |
\s |
匹配空白,即空格,tag键 |
\S |
匹配非空白 |
\w |
匹配单词字符,即数字,小写字母,大写字母,下划线_ |
\W |
匹配非单词字符 |
举例:
>>> re.match(".","&and") #.匹配任意字符,除了\n,只要第一个匹配,后面的and都是无所谓了,match方法就是这样定义的。从字符串最左边开始匹配,只要都匹配正则表达式,字符串后面的多余部分可以随意
<_sre.SRE_Match object; span=(0, 1), match='&'> #匹配到就有返回值,match是匹配到的具体内容,即 给一个.匹配了最左边的第一个字符&。
>>> re.match(".","\n") #不匹配,就返回None
>>> re.match("[1234][a-z][A-Z]\d","1aZ9") #正则表达式的意思是第一个字符要满足在1-4范围内,第二个字符是小写字母a-z,第三个字符是大写字符A-Z,第四个字符是数字,后面的字符串刚好满足,所以返回了下面这串值。这里同样的1aZ9匹配,1aZ9#@@¥%¥也是匹配的。
<_sre.SRE_Match object; span=(0, 4), match='1aZ9'>
>> re.match("\w\W","a%224") #第一个匹配单词字符,第二个匹配非单词字符,后面的无所谓
<_sre.SRE_Match object; span=(0, 2), match='a%'>
>>> re.match("\w\W","ab")
第二部分,个数相关:
字符 |
功能含义 |
* |
匹配一个字符出现0次或者多次,即可有可无 |
+ |
匹配一个字符出现1次或者多次,至少出现一次 |
? |
一个字符出现1次或者0次,即要么出现1次要么不出现 |
{m} |
匹配个数,前面的字符出现了m次 |
{m,} |
匹配个数,前面的字符至少出现了m次 |
{m,n} |
匹配个数,前面的字符出现了m到n次 |
举例:
>>> re.match("\d*","1234aa") #\d出现了0次或者多次
<_sre.SRE_Match object; span=(0, 4), match='1234'> #匹配到的是1234
>>> re.match("\d*","abd")
<_sre.SRE_Match object; span=(0, 0), match=''> #匹配到空字符
>>> re.match("\d+","abd") #匹配不到,因为+意思是必须至少出现1次
>>> re.match("\d{11}","18510666666") #数字匹配11个
<_sre.SRE_Match object; span=(0, 11), match='18510666666'>
# 匹配手机号,分析:手机号第一个数字必须为1,第二个数字应该是3、4、5、8、9,第3个到第11个是任意数字,所以为:\d{9},表示9个数字,然后只能有11个数字,所以9个数字的后面加$表示匹配结束,只能匹配前面的11个数字
res = re.match(r"1[34589]\d{9}$", "13511111111")
>>> re.match("1[34589]\d{9}","12000000000") #第2个数字不满足,不匹配
>>> re.match("1[34589]\d{9}","13000000000r") #满足,匹配
<_sre.SRE_Match object; span=(0, 11), match='13000000000'>
第三部分,边界相关:
字符 |
功能含义 |
^ |
表示匹配一个字符的开头 |
$ |
表示匹配一个字符的结尾 |
\b |
匹配一个字符的边界 |
\B |
匹配非字符边界 |
还是上面的例子,匹配手机号:
>>> re.match("1[34589]\d{9}","13000000000r") #满足,匹配
上面这个正则表达式是匹配的,但是显然不对,手机号后面不应该有字母,怎么解决呢?在写完的正则表达式后加$即可
>>> re.match("1[34589]\d{9}$","13000000000r") #不满足,不匹配
如果要匹配一个:D:\\python\\test,怎么办?
>>> re.match("D:\\python\\test","D:\\python\\test") #这样写是不对的,python会把\解析为转义字符,如何能避免呢,下面这样写,在正则表达式的前面加r:
>>> re.match(r"D:\\python\\test","D:\\python\\test")
<_sre.SRE_Match object; span=(0, 14), match='D:\\python\\test'>
Ps:推荐每当写正则表达式的时候,不管后面有没有转义字符,都加r
re.match(r"^.+ve\B","ho ver") #\B表示前面的字符e不在边界
<_sre.SRE_Match object; span=(0, 5), match='ho ve'>
>>> re.match(r"^.+ve\b","ho ve r")
<_sre.SRE_Match object; span=(0, 5), match='ho ve'>
>>> re.match(r"\w+\b\s+\w+\b\s+\w+\b","I love python")
<_sre.SRE_Match object; span=(0, 13), match='I love python'>
|管道符,逻辑或符号,在正则表达式中一样表示或,即匹配|符号两边的任意一个表达式都可以
比如,匹配0-100的数字:
#分析:第一个|符号前面的表达式是0,匹配0,第二个是100,第三个是匹配两位数字或者1位数字,第一位数字是1-9,第2位数字是0-9,?意思是可以有可以没有。
re.match(r"0|100|[1-9][\d?]$","90")
<_sre.SRE_Match object; span=(0, 2), match='90'>
>>> re.match(r"0|100|[1-9][\d?]$","0")
<_sre.SRE_Match object; span=(0, 1), match='0'>
完善后:
>>> re.match(r"[1-9]?\d$|100","0") #0匹配了第二个\d$
<_sre.SRE_Match object; span=(0, 1), match='0'>
第四部分,分组:
字符 |
功能含义 |
| |
匹配左右任意一个表达式 |
(ab) |
将括号中的字符作为一个分组 |
\num |
引用分组num匹配到的字符串 |
(?P<name>) |
给分组起名字 |
(?P=name) |
引用分组的名字 |
举例:
#定义一个字符串s
S=”<html><body><p>python</p></body></html>”
匹配上述的字符串,正则表达式如何写?
分析:第一个<html>跟最后一个</html>是一对,内容是一样的只是后面多了一个/,同理中间也是如此,这个时候可以使用分组的思想
先使用不分组的思想匹配:
res = r"<.+><.+><.+>.+</.+></.+></.+>"
>>> re.match(res,s)
<_sre.SRE_Match object; span=(0, 39), match='<html><body><p>python</p></body></html>'>
可以匹配到,然后使用分组思想,很简单,就是将<>里面的内容用()包起来,然后后面使用索引:
>>> res = r"<(.+)><(.+)><(.+)>.+</\3></\2></\1>"
>>> re.match(res,s)
<_sre.SRE_Match object; span=(0, 39), match='<html><body><p>python</p></body></html>'>
分析:第一个(.+)是分组的第一个索引,匹配到的内容是html,你希望最后一个<>内也是这个值,那么就在最后的位置,写\1表示匹配第一个分组的内容
有时分组内容太多,用索引会有可能乱掉,就可以使用起别名的方式,如下:
>>> res = r"<(?P<key1>.+)><(?P<key2>.+)><(?P<key3>.+)>.+</(?P=key3)></(?P=key2)></(?P=key1)>"
>>> re.match(res,s)
<_sre.SRE_Match object; span=(0, 39), match='<html><body><p>python</p></body></html>'>
原本第一个分组里面的内容是<(.+)>,想要起别名,就在.+的前面加上?P<key1>,后面引用这个别名的时候:(?P=key1),要注意括号必须有,有括号才表示分组
如果想获取<p></p>中间的内容,应该如何获取呢,或者你想要获取每一个分组的内容?
这时候可以使用group方法,接上面的:
>>> gr = re.match(res,s)
>>> gr.group() #不写索引值就默认把匹配到的所有值都打出来
'<html><body><p>python</p></body></html>'
>>> gr.group(1) #获取第一个分组
'html'
>>> gr.group(2) #获取第2个分组
'body'
>>> gr.group(3) # 获取第3个分组
'p'
>>> gr.group(4) #获取第4个分组报错了,因为没有第4个了
Traceback (most recent call last):
File "<input>", line 1, in <module>
IndexError: no such group
如果只想获取<p></p>中间的内容python,那你要把中间匹配到的内容用()括起来,表示也是一个分组:
>>> res = r"<(?P<key1>.+)><(?P<key2>.+)><(?P<key3>.+)>(.+)</(?P=key3)></(?P=key2)></(?P=key1)>"
>>> gr = re.match(res,s)
>>> gr.group(4)
'python'
第五部分,re模块的其他方法:
Search方法,从待匹配的字符串中检索出需要的,比如从”阅读次数为 999”字符串中检索出阅读次数:
>>> ret = re.search(r"\d+","阅读次数为:999")
>>> ret.group()
'999'
Search方法只能匹配到第1次的内容,比如:
>>> ret = re.search(r"\d+","阅读次数为:999,浏览次数为:2000")
>>> ret.group()
'999'
如果想要把所有的数字都找出来,可以使用findall方法,findall方法返回的是一个列表,没有group方法,可以直接打印列表
>>>ret = re.findall(r"\d+","阅读次数为:999,浏览次数为:2000")
>>> ret
['999', '2000']
Sub方法可以替换匹配到的字符串
>>> ret = re.sub(r"\d+","1000","阅读次数为:999 ")
>>> ret
'阅读次数为:1000 '
sub方法的第一个参数是正则表达式,第2个参数为替换后的数据,第三个参数是待匹配的字符串
第二个参数也可以为一个方法名,比如将阅读次数加1:
# 定义一个方法,有一个参数,接收匹配到的数据,并且返回一个数据
#sub方法会将匹配到的数据依次传到方法read_num中,所以我们首先要使用group方法获取到每个参数的具体内容,然后将这个字符串转为int类型,再加1,注意return的时候要转为字符串,这个位置的值只能是字符串
def read_num(num):
num_temp = num.group()
num = int(num_temp) + 1
return str(num)
s = "阅读次数为:999,浏览次数为2000"
ret = re.sub(r"\d+",read_num,s)
print(ret)
print结果:阅读次数为:1000,浏览次数为2001
# 将句子中的pho换成python
>>> ret = re.sub(r"php","python","I love php")
>>> ret
'I love python'
区分大小写:
>>> ret = re.sub(r"php","python","I love phP")
>>> ret
'I love phP'
Python中的贪婪和非贪婪
Python中默认的匹配时贪婪的(即尽可能多的匹配),那么如何能做到非贪婪呢?
在“*”“?”“+”“{m,n}”的后面加上?就可以做到非贪婪,尽可能少的匹配
比如:s="this is a number: 0312-265-8888",匹配出里面的电话号码,如果用下面第一种方法:
>>> ret = re.match(r".+(\d+-\d+-\d+)",s) #因为要匹配数字,所以把号码用括号括起来
>>> ret.group()
'this is a number: 0312-265-8888'
#这个结果是这种方式提取到的号码,明显不是我们想要的
>>> ret.group(1)
'2-265-8888'
这面这种方式就是贪婪方式,前面的.+尽可能的匹配多一些,后面的\d+只要有一个数字就可以满足,所以别的数字都归到了.+里面,在.+的后面加?后结果就不一样了:
>>> ret = re.match(r".+?(\d+-\d+-\d+)",s)
>>> ret.group(1)
'0312-265-8888'
加了?改成了非贪婪模式,那就是说尽可能多的匹配后面的\d+。
这个的group()方法,还有另外的类似方法是groups(),举例:
>>> ret = re.match(r"(.+?)(\d+-\d+-\d+)",s)
>>> ret.groups()
('this is a number: ', '0312-265-8888')
Groups方法返回一个元祖,每一个分组匹配到的字符串放到元祖里面。
上面的结果是加了?的,如果不加?,那么结果为:
>>> ret = re.match(r"(.+)(\d+-\d+-\d+)",s)
>>> ret.groups()
('this is a number: 031', '2-265-8888')
Split()方法的用法:
找出s中的单词
>>> s = "hi python,hello world"
#用,或者空格分隔s,返回一个列表,注意:|的后面有一个空格
>>> ret = re.split(r",+| +",s)
>>> ret
['hi', 'python', 'hello', 'world']
思考:
将多个http链接比如:http://www.51testing.com/?506458的后半部分去掉,只留下http://www.51testing.com/,如何做?
分析:后面这部分“?506458”不好匹配,但是前面比较有规律,思路就可以考虑匹配到前面的内容
>>> ret = re.sub(r"(http://.+?/).*",lambda x:x.group(1),s)
>>> ret
'http://www.51testing.com/'
解析:前面的正则表达式"(http://.+?/).*",可以匹配到的内容应该是整个http链接,把这个结果传入到lambda函数中,x的值就是正则表达式匹配的结果,然后x.group(1)就是将分组的第一个返回。这样就ok了。
Python的re模块,正则表达式书写方法的更多相关文章
- 【Python开发】Python之re模块 —— 正则表达式操作
Python之re模块 -- 正则表达式操作 这个模块提供了与 Perl 相似l的正则表达式匹配操作.Unicode字符串也同样适用. 正则表达式使用反斜杠" \ "来代表特殊形式 ...
- Python中optionParser模块的使用方法[转]
本文以实例形式较为详尽的讲述了Python中optionParser模块的使用方法,对于深入学习Python有很好的借鉴价值.分享给大家供大家参考之用.具体分析如下: 一般来说,Python中有两个内 ...
- Python 的 time 模块导入及其方法
时间模块很重要,Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能,讲解一下Python 的 time 模块导入及其方法. 1,time 模块导入 import time; # ...
- js中正则表达式 书写方法
function test(){ var text="index.aspx?test=1&ww=2&www=3"; var re = ...
- Python之re模块 —— 正则表达式操作
这个模块提供了与 Perl 相似l的正则表达式匹配操作.Unicode字符串也同样适用. 正则表达式使用反斜杠" \ "来代表特殊形式或用作转义字符,这里跟Python的语法冲突, ...
- Python之re模块正则表达式
re模块用于对python的正则表达式的操作 字符: .匹配除换行符以外的任意字符 \w匹配字母或数字或下划线或汉字 \s匹配任意空白符 \b匹配单词的开始或结束 ^匹配字符串的开始 $匹配字符串的结 ...
- Python 之Re模块(正则表达式)
一.简介 正则表达式本身是一种小型的.高度专业化的编程语言,而在python中,通过内嵌集成re模块,程序媛们可以直接调用来实现正则匹配. 二.正则表达式中常用的字符含义 1.普通字符和11个元字符: ...
- Python下OS模块重命名方法renames
在python中有很多强大的模块,其中我们经常要使用的就是OS模块,OS模块提供了超过200个方法来供我们使用,并且这些方法都是和数据处理相关的,这里介绍下重命名这个方法. OS的重命名方法是os.r ...
- Python:urllib模块的urlretrieve方法
转于:https://blog.csdn.net/fengzhizi76506/article/details/59229846 博主:fengzhizi76506 1)功能: urllib模块提供的 ...
随机推荐
- lqb 基础练习 查找整数 (遍历)
基础练习 查找整数 时间限制:1.0s 内存限制:256.0MB 问题描述 给出一个包含n个整数的数列,问整数a在数列中的第一次出现是第几个. 输入格式 第一行包含一个整数n. 第二行包含 ...
- lqb 基础练习 十进制转十六进制
基础练习 十进制转十六进制 时间限制:1.0s 内存限制:512.0MB 问题描述 十六进制数是在程序设计时经常要使用到的一种整数的表示方式.它有0,1,2,3,4,5,6,7,8,9,A ...
- nyoj 484-The Famous Clock
484-The Famous Clock 内存限制:64MB 时间限制:1000ms 特判: No 通过数:2 提交数:2 难度:1 题目描述: Mr. B, Mr. G and Mr. M are ...
- 力扣(LeetCode)学生出勤记录I 个人题解
给定一个字符串来代表一个学生的出勤记录,这个记录仅包含以下三个字符: 'A' : Absent,缺勤 'L' : Late,迟到 'P' : Present,到场 如果一个学生的出勤记录中不超过一个' ...
- 什么是TCP, UDP, HTTP, HTTPS协议?
TCP 传输控制协议是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC793定义. TCP主要特点: 1. 面向连接: (1)应用程序在使用TCP协议之前,必须先建立TCP连接. ...
- web服务,ftp服务以及共享实现
在开始服务前一定要确保可以ping通外网,在虚拟机联网但ping 不通外网下 确认vim /etc/sysconfig/network-scripts/ifcfg-ens33 (nmcli conne ...
- 用.net core mvc 开发一个虽小但五脏俱全的网站
.net core mvc 发布有很长时间了,但是一直没有用过,最近突然想开发一个导航网站,于是就抽时间开发了一个专门为开发者使用的导航站点,想看的话请移步我的上一篇博客https://www.cnb ...
- Linux配置SSH和Xshell连接服务器
>>>>>Ubuntu安装和配置ssh教程 SSH分为客户端 openssh-client 和服务器 openssh-server,可以利用以下命令确认电脑 上是否安装了 ...
- 【Luogu P4779】dijkstra算法的堆优化
Luogu P4779 利用堆/优先队列快速取得权值最小的点. 在稠密图中的表现比SPFA要优秀. #include<iostream> #include<cstdio> #i ...
- Scala学习系列一
一 scala介绍 Scala是一门以java虚拟机(JVM)为目标运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言. 1) Scala 是一门多范式 (multi-parad ...