5.3 正则表达式和re模块
微视频
正则表达式是字符串,它包含文本和特殊字符。re模块可以执行正则表达式的功能。利用文字与特定字符的混合,可以定义复杂的字符串匹配与取代类型。
5.3.1 正则表达式的特定字符
正则表达式所用的特定字符如表5-2所示。
表5-2 正则表达式所用的特定字符
如果用户要在正则表达式内使用?、*、+或换行等符号,就必须使用表5-3所示的字符。
表5-3 正则表达式内的特殊字符
5.3.2 re模块的方法
re模块的主要功能是通过正则表达式来操作字符串。在使用re模块时,需要先使用import语句引入,语法格式如下:
import re
下面讲述re模块中常见的操作字符串的方法。
1.匹配字符串
通过re模块中的match()、search()和findall()方法可以匹配字符串。
(1)match()。match()方法用于从字符串的开始处进行匹配,如果在起始位置匹配成功,则返回Match对象;如果不是在起始位置匹配成功,则返回None。
match()方法的语法格式如下:
re.match(pattern, string, flags=0)
其中,参数pattern用于匹配的正则表达式;参数string用于要匹配的字符串;参数flags用于控制正则表达式的匹配方式,如是否区分大小写、多行匹配等。如果匹配成功,match()方法返回一个匹配的对象,否则返回None。
【例5.5】验证输入的手机号是否为中国移动的号码(源代码\ch05\5.5.py)。
这里首先需要导入re模块,然后定义一个验证手机号码的模式字符串,最后使用match()方法验证输入的手机号是否和模式字符串匹配。
import re #导入Python 的re 模块 print("欢迎进入中国移动电话号码验证系统") s1 = r'(13[4-9]\d{8})$|(15[01289]\d{8}$)' s2 = input("请输入需要验证的电话号码:") #输入需要验证的电话号码 match = re.match(s1,s2) #进行模式匹配 if match==None: #判断是否为None,为真表示匹配失败 print("您输入的号码不是中国移动的电话") else: print("您输入的号码是中国移动的电话")
程序运行结果如图5-5所示。
图5-5 例5.5的程序运行结果
(2)search()。search()方法用于扫描整个字符串并返回第一个成功的匹配。语法格式如下:
re.search(pattern, string, flags=0)
其中,参数pattern用于匹配的正则表达式;参数string用于要匹配的字符串;参数flags用于控制正则表达式的匹配方式,如是否区分大小写、多行匹配等。如果匹配成功,match()方法返回一个匹配的对象,否则返回None。
与match()方法不同的是,search()方法既可以在起始位置匹配,也可以不在起始位置匹配。
例如下面的代码:
import re print(re.search('www', 'www.bczj123.com').span()) #在起始位置匹配 print(re.search('123', 'www.bczj123.com').span()) #不在起始位置匹配
运行结果如下:
(0, 3) (8, 11)
【例5.6】敏感字过滤系统(源代码\ch05\5.6.py)。
假设敏感字为渗透、攻击、脚本,如果输入的字符串中含有敏感字中的任意一个,将会有警告提示,否则安全通过。
import re #导入Python 的re 模块 print("欢迎进入敏感字过滤系统") s1 = r'(渗透)|(攻击)|(脚本)' #模式字符串 s2 = input("请输入需要验证的文字:") #输入需要验证的字符串 match = re.search(s1,s2) #进行模式匹配 if match==None: #判断是否为None,为真表示匹配失败 print("您输入的文字安全通过!!") else: print("警告!您输入的文字存在敏感字,请重新整理后输入!")
程序运行结果如图5-6所示。
图5-6 例5.6的程序运行结果
☆大牛提醒☆
match()方法只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而search()方法匹配整个字符串,直到找到一个匹配项。
(3)findall()。findall()方法用于在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配项,则返回空列表。
☆大牛提醒☆
match()和search()方法是匹配一次,而findall()方法匹配所有。
findall()的语法格式如下:
findall(string[, pos[, endpos]])
其中,参数string是待匹配的字符串;pos为可选参数,指定字符串的起始位置,默认为0;endpos为可选参数,指定字符串的结束位置,默认为字符串的长度。
【例5.7】数字挑选系统(源代码\ch05\5.7.py)。
对输入的字符串进行挑选,如果发现数字,挑选出来。
import re #导入Python 的re 模块 print("欢迎进入数字挑选系统") s1 = re.compile(r'\d+') #查找数字 s2 = input("请输入需要挑选的字符串:") #输入需要挑选的字符串 result = s1.findall(s2) print(result)
程序运行结果如图5-7所示。
图5-7 例5.7的程序运行结果
2.替换字符串
通过re模块中的sub()方法可以替换字符串中的匹配项。语法格式如下:
re.sub(pattern, repl, string, count=0, flags=0)
其中,参数pattern是正则表达式中的模式字符串;repl是要替换的字符串,也可为一个函数;参数string要被查找替换的原始字符串;参数count是模式匹配后替换的最大次数,默认为0,表示替换所有的匹配项。
【例5.8】替换字符串中的非数字和特殊符号(源代码\ch05\5.8.py)。
import re numb = "0408-1111-1189 #这是一个学生的编号" #删除字符串中的 Python 注释 nums = re.sub(r'#.*$', "", numb) print ("学生的编号是: ", nums) #删除非数字(-)的字符串 numd = re.sub(r'\D', "", numb) print ("学生的新编号是: ", numd)
程序运行结果如图5-8所示。
图5-8 例5.8的程序运行结果
3.分割字符串
通过re模块中的split()方法可以分割字符串。split()方法按照能够匹配的子串将字符串分割后返回列表。语法格式如下:
re.split(pattern, string[, maxsplit=0, flags=0])
其中,参数pattern是正则表达式中的模式字符串;参数string为要被分割的字符串;参数maxsplit是分隔次数,maxsplit=1表示分隔一次,默认为0,不限制次数;参数flags用于控制正则表达式的匹配方式,如是否区分大小写、多行匹配等。
【例5.9】使用正则表达式输出被标星的好友(源代码\ch05\5.9.py)。
import re s1 = "*张三丰*李一真*陶渊明*李白" pattern = r'\*' ls= re.split(pattern,s1) #以*分隔字符串 print ("您的标星好友是:") for im in ls: if im != " ": #输出不为空的元素 print(im) #输出每个好友时,去掉*符号
程序运行结果如图5-9所示。
图5-9 例5.9的程序运行结果