python--关于正则表达式的学习小结
python中提供了re这个模块提供对正则表达式的支持。
一、正则表达式常用到的一些语法(并非全部):
| . | 匹配任意单个字符 |
| [...] | 匹配单个字符集 |
| \w | 匹配单词字符,即[a-zA-Z0-9] |
| \W | 匹配非单词字符集,例如 ‘*’ |
| \d | 匹配数字,即[0-9] |
| \D | 匹配非数字 |
| \s | 匹配空白字符 |
| \S | 匹配非空白字符 |
| * | 匹配前一个字符0次或者任意多次 |
| + | 匹配前一个字符1次或者任意多次 |
| ? | 匹配前一个字符0次或者1次 |
| {m} | 匹配前一个字符m次 |
| {m,n} | 匹配前一个字符最少m次,最多n次 |
| *? | 非贪婪模式匹配前一个字符0次或者任意多次 |
| +? | 非贪婪模式匹配前一个字符1次或者任意多次 |
| ?? | 非贪婪模式匹配前一个字符0次或者1次 |
| {m,n}? | 非贪婪模式匹配前一个字符最少m次,最多n次 |
| ^ | 匹配字符串开头 |
| $ | 匹配字符串结尾 |
| \A | 制定的字符串匹配必须出现在开头 |
| \Z | 制定的字符串匹配必须出现在结尾 |
| | | 匹配左右任意一个表达式,相当于“或”的含义 |
| () | 匹配一个分组,括号中为该分组所需匹配的内容 |
| \<number> | 引用匹配编号为<number>的分组中的字符串 |
| (?P<group_name>) | 为匹配分组制定特定的组名 |
| (?P=<group_name>) | 引用特定组名的匹配字符串 |
几点解释:
1. 两种方式都可以进行匹配:
(1)首先创建pattern,然后进行match
1 pa = re.compile(r'[\w]{6}') # 首先利用re模块创建一个pattern实例pa
2 ma = pa.match('string') # 利用这一pattern对正则表达式进行匹配
3 ma.group() #打印匹配的内容,输出为'string'
(2)直接利用re模块中的函数match进行匹配
1 ma = re.match(r'[\w]{6}', ‘string’)
2 print(ma.group()) # 打印匹配的内容,输出为'string'
2. 贪婪模式和非贪婪模式:
贪婪模式:总是尝试匹配尽可能多的字符;
非贪婪模式:总是尝试匹配尽可能少的字符。
例如:利用正则表达式‘python*’匹配‘pythonnnnnpython’,此时ma = re.match(r'python*',‘pythonnnpython’),得到的ma.group()为‘pythonnn’;利用‘python*?’进行匹配,此时ma = re.match(r'python*?',‘pythonnnpython’),得到的ma.group()为‘python’。
3. 关于逻辑与分组语法的用法:
| | | 匹配左右任意一个表达式,相当于“或”的含义 |
| () | 匹配一个分组,括号中为该分组所需匹配的内容 |
| \<number> | 引用匹配编号为<number>的分组中的字符串 |
| (?P<group_name>) | 为匹配分组制定特定的组名 |
| (?P=<group_name>) | 引用特定组名的匹配字符串 |
首先,|和()的用法比较容易理解,例如我们需要匹配多个邮箱的地址是否合法,例如有gmail邮箱、outlook邮箱,假定@前的字符数为6到20个,此时可以写成:
|
1
2
3
4
5
6
7
|
>>> pa = re.compile('[\w]{6,20}@(gmail|outlook).com$')>>> ma = pa.match('bokeyuan@gmail.com')>>> ma.group()'bokeyuan@gmail.com'>>> ma = pa.match('bokeyuan@outlook.com')>>> ma.group()'bokeyuan@outlookl.com' |
后边三个的用法根据下边的例子进行说明:
|
1
2
3
4
5
6
7
8
9
10
|
>>> str = '<code>python</code>'>>> ma = re.match(r'<[\w]+>', str)>>> ma.group()'<code>'>>> ma = re.match(r'<([\w]+>)[\w]+</\1', str)>>> ma.group()'<code>python</code>'>>> ma = re.match(r'<(?P<group1>[\w]+>)[\w]+</(?P=group1)', str)>>> ma.group()'<code>python</code>' |
其中,第一个例子就是对字符串‘<code>'进行匹配。我们发现str中其实有两部分是完全相同的,就是都含有'code>'这个substring,于是可以看第二个例子,我们用()将([\w]+>)这部分内容括住时,这部分匹配的字符串就是'code>',([\w]+>)就是一个分组,没有起名字的情况下默认<number>为1,因此在我们需要在末尾再次引用到它的时候,就写上 /1 即可。第三个例子与第二个例子的效果完全相同,只不过为了更加清楚的记住匹配分组的名字,我们利用(?P<group_name>)这一语法功能,人为的为这个分组取了一个group1的名字,在最后又引用了这一分组。
4. 注意字符串中转义字符的问题
上述例子中,出现在正则表达式前边的r是原始字符串操作符,可以写为r或者R:表示字符串内的所有字符都按原始意思解释。
例如:‘c:\python\test.py’ 如果不加r,则计算机会将 \t 会变成转义字符解释;加上r以后,写为:r‘c:\python\test.py’,计算机就会直接输出c:\python\test.py,否则要想输出c:\python\test.py,必须将字符串写为‘c:\\python\\test.py’
二、介绍几个re模块中的常用函数
1. search(pattern, string, flags=0)函数
search函数功能:在字符串中查找匹配
例如:博客会记录来访者的数量,我们通过正则匹配查找字符串中的数字:
1 str1 = 'number of visitors = 1000'
2 info = re.search(r'\d+', str1) # 匹配字符串str1中的数字
3 print('访客数量:', info)
4 print(info.group()) # 显示匹配的内容
当然,上述操作也可以通过对字符串直接操作获得,例如:print('访客数量:', str1.find('1000')) 。但是这样存在一个问题,因为访客数量实在不断变化的,一旦1000这个数字增加,用字符串操作就难以实现。但是利用search函数就不存在这样的问题。
2. findall(pattern, string, flags=0)函数
findall函数功能:找到匹配,并返回所有匹配内容的列表
例如,博客记录了最近三天每天的访客记录,我们需要将三天的访客数量都查找出来,并计算总的访客数量,此时用search函数无法直接将三天的访客数量同时提取,可以采用findall函数:
1 str2 = 'day1=22, day2=34, day3=13'
2 info = re.findall(r'=[\d]+', str2)
3 print(info)
4 print('三天的访客数量为:', sum([int(x[1:]) for x in info]))
3. sub(pattern, repl, string, count=0, flags=0)函数
sub函数功能:将字符串中匹配正则表达式的部分替换为其他值。其中repl可以是一个字符串,也可以是一个函数。
当repl是一个字符串时,仍然以访客记录为例,当增加一个访客时,需要修改记录中的数字:
1 str3 = 'number of visitors = 1000'
2 info = re.sub(r'[\d]+', '1001', str3)
3 print(info) # 此时输出结果为 number of visitors = 1001
但是此时每次修改都必须手动输入数字,显然,对于这种随时变化的数字来说,这种操作是不合理的。而sub函数的高明之处就是允许repl是一个函数。
当repl为一个函数时,首先会在string中查找pattern的匹配,查找到的匹配是一个match对象,这个match对象就会被传递到repl这个函数中。上述例子可以这样实现:

1 # 首先,定义一个增加访客数量的函数,函数的参数是一个match对象
2 def add_num(match):
3 val = match.group()
4 num = int(val) + 1
5 return str(num)
6
7 str3 = 'number of visitors = 1000'
8 print('最新访客数量:', re.sub(r'[\d]+', add_num, str3)) # 打印结果,最新访客数量:number of visitors = 1001

4. split(pattern, string, maxsplit=0, flags=0)函数
split函数功能:根据匹配分割字符串,返回分割字符串组成的列表
1 str4 = 'day1=22, day2=34, day3=13'
2 print(re.split(r', ', str4)) # 打印出的内容为 ['day1=22', 'day2=34', 'day3=13']
python--关于正则表达式的学习小结的更多相关文章
- python学习笔记(一)——关于正则表达式的学习小结
python中提供了re这个模块提供对正则表达式的支持. 一.正则表达式常用到的一些语法(并非全部): . 匹配任意单个字符 [...] 匹配单个字符集 \w 匹配单词字符,即[a-zA-Z0-9] ...
- Python html.parser库学习小结
分类路径:/Datazen/DataMining/Crawler/ 前段时间,一朋友让我做个小脚本,抓一下某C2C商城上竞争对手的销售/价格数据,好让他可以实时调整自己的营销策略.自己之前也有过写 ...
- PYTHON HTML.PARSER库学习小结--转载
前段时间,一朋友让我做个小脚本,抓一下某C2C商城上竞争对手的销售/价格数据,好让他可以实时调整自己的营销策略.自己之前也有过写爬虫抓某宝数据的经历,实现的问题不大,于是就答应了.初步想法是利用pyh ...
- python re(正则表达式模块)学习
一.简介 正则表达式本身是一种小型的.高度专业化的编程语言,而在python中,通过内嵌集成re模块,程序媛们可以直接调用来实现正则匹配.正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎 ...
- 基于Windows平台的Python多线程及多进程学习小结
python多线程及多进程对于不同平台有不同的工具(platform-specific tools),如os.fork仅在Unix上可用,而windows不可用,该文仅针对windows平台可用的工具 ...
- Python 学习小结
python 学习小结 python 简明教程 1.python 文件 #!/etc/bin/python #coding=utf-8 2.main()函数 if __name__ == '__mai ...
- python --- 字符编码学习小结(二)
距离上一篇的python --- 字符编码学习小结(一)已经过去2年了,2年的时间里,确实也遇到了各种各样的字符编码问题,也能解决,但是每次都是把所有的方法都试一遍,然后终于正常.这种方法显然是不科学 ...
- 第二十一天python3 python的正则表达式re模块学习
python的正则表达式 python使用re模块提供了正则表达式处理的能力: 常量 re.M re.MULTILINE 多行模式 re.S re.DOTALL 单行模式 re.I re.IGNORE ...
- python study - 正则表达式
第 7 章 正则表达式 7.1. 概览 7.2. 个案研究:街道地址 7.3. 个案研究:罗马字母 7.3.1. 校验千位数 7.3.2. 校验百位数 7.4. 使用 {n,m} 语法 7.4.1. ...
随机推荐
- python线程+队列(queue)
---恢复内容开始--- python的线程学习 用处 pocpiliang脚本的编写 函数式:调用 _thread 模块中的start_new_thread()函数来产生新线程.语法如下: _thr ...
- oracle行转列和列转行(pivot 和 unpivot 函数,wm_concat函数 )
create table demo(id int,name varchar(20),nums int); ---- 创建表insert into demo values(1, '苹果', 1000); ...
- Protocol Buffers学习笔记
Protocol Buffers学习笔记 1. 简介 Protocol Buffers是google发明的一种数据交换格式,独立于语言,独立于平台.与其他的数据交换格式有所不同,Protocol Bu ...
- 网络文件共享服务—vsftpd服务
文件传输协议(FTP) 文件传输协议:File Transfer Protocol是用于在网络上进行文件传输的一套标准协议,使用客户/服务器模式.它属于网络传输协议的应用层. 服务器端:vsftpd ...
- go -- application/x-www-form-urlencoded发送post数据
- C 习题
1,日本某地发生命案,警察通过排查确定4个人中一个人为凶手,一下为4个人的供词, A:不是我 B:是C C:是D D:C说谎 解决方式: #include<stdio.h> int mai ...
- mysql数据库每个表的备份脚本
对mysql数据库中的每张表进行按日期备份,思想是:先把每张表的表名取出取出,然后通过for循环去对每个表进行按日期备份 [root@ZFVM-APP-- backup]# vim dataname. ...
- 【Java/MySql】使用JDBC访问MySql数据库的Maven工程
下载链接:https://files.cnblogs.com/files/xiandedanteng/FindNotnullColumns20191102-1.rar pom.xml里写: <p ...
- Maven 引入外部依赖
pom.xml 的 dependencies 列表列出了我们的项目需要构建的所有外部依赖项. 要添加依赖项,我们一般是先在 src 文件夹下添加 lib 文件夹,然后将你工程需要的 jar 文件复制到 ...
- JAVA NIO学习笔记二 频道和缓冲区
Java NIO 频道 Java NIO渠道类似于流,他们之间具有一些区别的: 您可以读取和写入频道.流通常是单向(读或写). 通道可以异步读取和写入数据. 通道常常是读取或写入缓冲区. 如上所述,您 ...