什么是re模块,re模块有什么作用?

re模块是Python提供的一个正则表达式相关的模块,主要是针对字符串进行模糊匹配,所以在字符串匹配这一功能上,re相当专业。

什么是模糊匹配?

之前的学习字符串内容的时候,也有进行匹配的一些方法,比如find()方法:

S = 'adnsanpnqbciqwocb'
ret = S.find('san')
print(ret)
>>> 3

这样就可以获得"san"在S中的位置,这种方法称为精确匹配。但很多情况下我们提供的搜索条件并没有那么精确,比如“四条腿”,在大脑中检索出来的答案就有四条腿的桌子、四条腿的兔子等等,这种粗略的搜索就可以理解为模糊匹配

在re中,匹配的参数可以是普通字符,也可以是元字符,这里用re中最常用的findall()函数举例,findall()函数就是找出目标字符串中所有的复合模板要求的字符串。

import re

ret = re.findall('pengfy','dainbqbfepengfyxMONDW434')
print(ret)
>>> ['pengfy']

元字符主要有:. ^ $ * + ? {} [] () | \

我们在findall()函数中中演示这几个元字符的用法,先看元字符 . ^ $ * + ? {}

.叫通配符能能够代表任意字符(\n除外),需要代表几个就写几个.,举例如下:

import re

ret = re.findall('p..g','d123pengfyPENGFYpANgyq')
print(ret) #找出所有p开头g结尾的字符串,区分大小写
>>>['peng', 'pANg'] ret = re.findall('p..g','d123pe\ngfy')
print(ret) #不能代表\n
>>>[]

^我们老师管它叫尖角符,只能从字符串的开头进行匹配,$刚好相反,只能从字符串的结尾进行匹配,举例如下:

(注意^和$放的位置,也是一头一尾)

import re

ret = re.findall('^p..g','pengfyPENGFYpANgyq')
print(ret) #只能从头开始匹配
>>> ['peng'] ret = re.findall('p..g$','pengfyPENGFYpANgyqpang')
print(ret) #只能从尾部开始匹配
>>>['pang'] ret = re.findall('^p..g$','pengfyPengFYpANg')
print(ret) #一起使用不会报错,但也不会有结果,这不是一种有效的用法
>>>[]

如果有多个重复的字母,我们用.表示显然很麻烦,这种情况我们可以用* + {}

*表示可以重复0或多次

+表示可以重复1或多次

{}可以指定重复的次数

一定程度上,{}可以表示成* +

分别举例如下:

import re

ret = re.findall('peng*','6ghpenggggggfwf')
print(ret)
>>>['pengggggg'] ret = re.findall('peng*','6ghpenfwf')
print(ret)
>>>['pen'] ret = re.findall('peng+','6ghpenggggggfwf')
print(ret)
>>>['pengggggg'] ret = re.findall('peng+','6ghpenfwf')
print(ret) #和*的区别
>>>[] ret = re.findall('peng{0,8}','6ghpenggggggfwf')
print(ret)
>>>['pengggggg'] ret = re.findall('peng{0}','6ghpenggggggfwf')
print(ret)
>>>['pen'] ret = re.findall('peng{0,}','6ghpenggggggfwf')
print(ret) #不加逗号就只匹配0个g,加上就默认0到无穷,和*一样
>>>['pengggggg'] ret = re.findall('peng{8}','6ghpenggggggfwf')
print(ret)
>>>[] #指定个数没达到,就没有匹配值 ret = re.findall('peng{}','6ghpenggggggfwf')
print(ret) #不指定区间,也没有匹配值
>>> []

通过以上实例,大家可以看到,只要匹配到的,我们都是返回重复最多的结果,这种匹配叫贪婪匹配,如何取消,那就是使用问号 ?,举例如下:

import re
ret = re.findall('peng*?','6ghpenggggggfwf')
print(ret) #最小重复0次
>>>['pen'] ret = re.findall('peng+?','6ghpenggggggfwf')
print(ret) #最小重复1次
>>>['peng'] ret = re.findall('peng{2,8}?','6ghpenggggggfwf')
print(ret) #最小重复指定次数,这里是2
>>>['pengg']

可以看到,加上?后,匹配的都变成了最小重复次数,这种匹配叫惰性匹配

接下来看[],还是举例说明:

import re

ret = re.findall('www.[taobao,baidu].com','wwwww.baidu.commmm')
print(ret)
>>>[] ret = re.findall('www.[taobao,baidu].com','wwwww.b.commmm')
print(ret)
>>>['www.b.com'] ret = re.findall('www.[taobao,baidu].com','wwwww.,.commmm')
print(ret)
>>>['www.,.com']

通过上面的例子可以看到,[]里面,每个元素都独立存在,包括逗号,里面的关系可以理解成或的关系,但是在[]中的元素基本都没有自身的意义,

但有三个符号是有意义的,分别是 - ^ \

import re

ret = re.findall('[a-z]','AJo;AHIcnwi1890jlk')
print(ret) #按ASSIC码表区范围
>>>['o', 'c', 'n', 'w', 'i', 'j', 'l', 'k'] ret = re.findall('[^a-z]','AJo;AHIcnwi1890jlk')
print(ret)
>>>['A', 'J', ';', 'A', 'H', 'I', '', '', '', ''] ret = re.findall('[a\-z]','AJo;AHIcnwz1890jlk')
print(ret) #取消了-的特殊功能,[]中就剩下a或-或z三个元素
>>>['z'] ret = re.findall('[\^a-z]','AJo;AHIcnwi1890jlk')
print(ret) #取消了^的特殊功能,[]中就剩下^和a-z之间的字母
>>>['o', 'c', 'n', 'w', 'i', 'j', 'l', 'k'] ret = re.findall('[c\.w]','AJo;AHIcnwi1890j.lk')
print(ret) #取消了.的特殊功能,[]中就剩下c或.或w三个元素
>>>['c', 'w', '.']

前面两个比较好理解,-就是一个范围,^就是非的意思,只要不是[]中的元素就可以匹配,\的功能就是取消元字符的特殊功能,但\还有一个功能,下面开始讲解\

1.反斜杠后边跟元字符去除特殊功能,比如\.
2.反斜杠后边跟普通字符实现特殊功能,比如\d

第一个上面已经演示过了,下面看第二个功能:

\d  匹配任何十进制数;它相当于类 [0-9]。
\D 匹配任何非数字字符;它相当于类 [^0-9]。
\s  匹配任何空白字符;它相当于类 [ \t\n\r\f\v]。
\S 匹配任何非空白字符;它相当于类 [^ \t\n\r\f\v]。
\w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
\W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
\b  匹配一个特殊字符边界,比如空格 ,&,#等

还是通过实例展示一下:

import re

ret = re.findall('\d','AJo;AHIcnwi1890j.lk')
print(ret)
<<<['', '', '', ''] ret = re.findall('\D','AJo;.lk')
print(ret)
>>>['A', 'J', 'o', ';', '.', 'l', 'k'] ret = re.findall('\s','I am Pengfy')
print(ret)
>>>[' ', ' '] ret = re.findall('\S','I am Pengfy')
print(ret)
>>>['I', 'a', 'm', 'P', 'e', 'n', 'g', 'f', 'y'] ret = re.findall('\w','I am,18YEARSOLD.')
print(ret)
>>>['I', 'a', 'm', '', '', 'Y', 'E', 'A', 'R', 'S', 'O', 'L', 'D'] ret = re.findall('\W','I am,18YEARSOLD.')
print(ret)
>>>' ', ',', '.'] ret = re.findall('I\b','Y&I are boy')
print(ret)
>>>[]

前面几个应该都能理解,看到最后一个,什么鬼,怎么没有返回数据啊?不要慌,这里要从Python运行机制去解释,先看下面几个例子:

import re

ret=re.findall('y\z','penfgy\ze')
print(ret) #程序报错:bad escape \z at position 1 ret=re.findall('y\\z','penfgy\ze')
print(ret) #程序报错:bad escape \z at position 1 ret=re.findall('y\\\\z','penfgy\ze')
print(ret)
>>>['y\\z'] ret=re.findall(r'y\\z','penfgy\ze')
print(ret)
>>>['y\\z']

我们可以看到,需要传四个反斜杠才能输出正常结果,为什么呢?因为\是给re模块识别的,但是在Python解释器中,\b又有别的意思,所以需要加一个r,至于为什么我们看到的结果为什么是两个反斜杠,这也是解释器的原因导致,其实在re中是一个。

ret = re.findall(r'I\b','I am Iboy &I is')
print(ret)
>>>['I', 'I']

加上r以后,就能正常匹配了,r是干什么的呢?r的作用就是告诉解释器,里面的东西不要编译,原封不动的给到re

还剩下()和管道符 |,()是用于分组,比如:

import re

ret=re.findall(r'(ab)+','abbbbbbcd')
print(ret)
>>>['ab'] # 为什么只匹配到了一个?因为()的优先级比+高,使用?就可以取消他的优先级,这样写(?:ab)+ import re
ret=re.findall(r'(bcd)','abbbbbbcdbcdbcd')
print(ret)
>>>['bcd', 'bcd', 'bcd'] ret=re.findall('(?P<id>\d{2})/(?P<name>\w{3})','23/com23com255/yyyy')
print(ret)
>>>[('', 'com'), ('', 'yyy')] ret=re.search('(?P<id>\d{2})/(?P<name>\w{3})','23/com23com255/yyyy')
print(ret) #返回的只是一个地址
print(ret.group())
print(ret.group('name')) #可以单独取一个
>>> <re.Match object; span=(0, 6), match='23/com'>
>>> 23/com
>>> com

上面(?P<id>)这种用法直接记住就好了,原理很难讲清楚。接下来看管道符的用法:

import re

ret=re.findall('www.baidu|google.com','www.baidu.com,www.google.com')
print(ret) #管道两边是或的关系
>>> ['www.baidu', 'google.com']

到这里,元字符的用法就讲完了,下面讲一下re模块中的其他函数用法,re模块主要有findall() search() match() split() sub() compile() finditer()几个函数:

search()函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

import re
ret = re.search('p..g','666pengfy888pangyq').group()
print(ret)
>>> peng

match()函数和search()函数用法相同,但只能匹配字符串的开头

ret = re.match('p..g','666pengfy888pangyq')
print(ret) #这里返回一个None,加上group()就报错了
>>> None ret = re.match('p..g','pengfy888pangyq').group()
print(ret)
>>> peng

split()看起来并不陌生,在字符串的处理中也有一样的方法,这个就可以选择按什么方法进行切割:

ret = re.split('[bc]','abcde')
print(ret) #这里是先按b分割成a、cde,cde再按c分割成''、de
>>> ['a', '', 'de']

sub(),作用是替换,字符串中类似方法叫replace,直接看实例:

import re

set = re.sub('\d','peng','haoren66haode546fwerwef',2)
print(set) #后面2这个参数,是替换的个数,本例中表示就替换前2个
print(type(set)) #输出的会是一个字符串 >>> haorenpengpenghaode546fwerwef
>>> <class 'str'>

compile()的目的就是将匹配的方法赋值,这样使用多次的时候回相对简单一些:

func = re.compile('p..g*')
ret = func.findall('penggggfy888panggyq')
ret1 = func.search('penggggfy888panggyq').group()
print(ret,ret1)
>>>['pengggg', 'pangg'] pengggg

finditer(),一看这个名字diter,其实就是iterator迭代器,用法和findall()差不多,然后使用next方法一个个取出来就好了:

ret = re.finditer('p..g+','666penggggfy888panggyq')
print(ret)
print(next(ret).group())
print(next(ret).group()) >>><callable_iterator object at 0x000001F6CA11E908>
>>>pengggg
>>>pengg

以上就是对re模块的总结。

Python的re模块的更多相关文章

  1. python之platform模块

    python之platform模块 ^_^第三个模块从天而降喽!! 函数列表 platform.system() 获取操作系统类型,windows.linux等 platform.platform() ...

  2. python之OS模块详解

    python之OS模块详解 ^_^,步入第二个模块世界----->OS 常见函数列表 os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows ...

  3. python之sys模块详解

    python之sys模块详解 sys模块功能多,我们这里介绍一些比较实用的功能,相信你会喜欢的,和我一起走进python的模块吧! sys模块的常见函数列表 sys.argv: 实现从程序外部向程序传 ...

  4. 学习PYTHON之路, DAY 6 - PYTHON 基础 6 (模块)

    一 安装,导入模块 安装: pip3 install 模块名称 导入: import module from module.xx.xx import xx from module.xx.xx impo ...

  5. linux下python调用c模块

    在C调用Python模块时需要初始化Python解释器,导入模块等,但Python调用C模块却比较简单,下面还是以helloWorld.c 和 main.py 做一说明:   (1)编写C代码,hel ...

  6. Python学习之模块进程函数详解

    今天在看<Beginning Linux Programming>中的进程相关部分,讲到Linux几个进程相关的系统函数: system , exec , fork ,wait . Pyt ...

  7. python基础——第三方模块

    python基础——第三方模块 在Python中,安装第三方模块,是通过包管理工具pip完成的.  如果你正在使用Mac或Linux,安装pip本身这个步骤就可以跳过了.  如果你正在使用Window ...

  8. python基础——使用模块

    python基础——使用模块 Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用. 我们以内建的sys模块为例,编写一个hello的模块: #!/usr/bin/env ...

  9. python 中time模块使用

    在开始之前,首先要说明这几点: 1.在Python中,通常有这几种方式来表示时间:1)时间戳 2)格式化的时间字符串 3)元组(struct_time)共九个元素.由于Python的time模块实现主 ...

  10. Python之logging模块

    一.引言 之前在写一些小程序的时候想把日志内容打到文件中,所以就自己写了一个logger.py的程序,如下: #!/usr/bin/python # -*- coding=utf-8 -*- impo ...

随机推荐

  1. View requires API level 14 (current min is 8): <GridLayout>

    在学习android的过程中,出现这个错误的是否,可以build clean解决

  2. RDC去省赛玩前の日常训练 Chapter 2

    2018.4.9 施展FFT ing! 马上就要和前几天学的斯特林数双剑合璧了!

  3. 解决0% [Waiting for headers] 导致的unable to lock the administration directory (/var/lib/dpkg/) is another process using it

    这是我在配置vim的YouCompleteMe时遇到的问题,我需要使用CMake来编译YCM. 在我输入 $ sudo apt install cmake 由于网络原因导致安装一直卡在0% [Wait ...

  4. 使用Java API连接和操作HBase数据库

    创建的数据库存储如下数据 表结构 java代码 public class HbaseTest { /** * 配置ss */ static Configuration config = null; p ...

  5. jsp 条件查询、列表分页

    条件查询 dao //根据搜索条件筛选数据 public List<User> GetUserBySearch(String userName, String sex) throws SQ ...

  6. msql索引

    从网上找了两种解决方案: 最近要给一个表加一个联合唯一索引,但是表中的两个联合健有重复值,导致无法创建: 解决方案一:ignore(会删除重复的记录(重复记录只保留一条,其他的删除),然后建立唯一索引 ...

  7. vue中keep-alive的用法

    1.keep-alive的作用以及好处 在做电商有关的项目中,当我们第一次进入列表页需要请求一下数据,当我从列表页进入详情页,详情页不缓存也需要请求下数据,然后返回列表页,这时候我们使用keep-al ...

  8. linux独有的sendfile系统调用--“零拷贝,高效”

    参考:http://blog.csdn.net/caianye/article/details/7576198 如今几乎每个人都听说过Linux中所谓的"零拷贝"特性,然而我经常碰 ...

  9. eclipse换了高版本的maven插件后报错:org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project

    在给eclipse换了高版本的maven插件后,引入jar包报如下的错误:  org.apache.maven.archiver.MavenArchiver.getManifest(org.apach ...

  10. webstorm-快捷键大全

    Webstorm快捷键 Eclipse快捷键 说明 ctrl+shift+N ctrl+shift+R 通过文件名快速查找工程内的文件(必记) ctrl+shift+alt+N ctrl+shift+ ...