通过正则表达式可以定义一些匹配规则,只要满足匹配规则即认为匹配成功,从而实现模糊匹配。
正则表达式中既可以包含普通字符,也可以包含由特殊字符指定的匹配模式。
在实际应用正则表达式进行匹配时,正则表达式中的普通字符需要做精确匹配,而特殊字符指定的匹配模式则对应了用于模糊匹配的规则。
正则表达式的基础语法
部分匹配模式
特殊序列
re模块使用-compile
compile函数用于将一个字符串形式的正则表达式编译成一个正则表达式对象,供match、search以及其他一些函数使用。其语法格式为:
re.compile(pattle,flags=0)
# pattern是一个字符串形式的正则表达式;
# flags指定了匹配选项(默认为0,表示没有任何匹配选项),可以使用按位或(|)运算符将多个选项连接起来。
使用compile函数的优点在于:当一个正则表达式在程序中被多次使用时,通过compile函数生成的正则表达式对象可重复使用,从而提高效率。
除了直接调用re模块中的match函数外,也可以使用compile函数生成的正则表达式对象中的match方法实现同样的功能,其语法格式为:
Pattern.match(string,[pos[,endpos]])
# Pattern是compile函数返回的正则表达式对象;
# string是要做正则表达式匹配的字符串;
# 可选参数pos指定了从string的那个位置开始进行匹配,默认为0;
# 可选参数endpos指定了string的结束位置。
# match函数将对string函数中pos至end pos-1范围的子串进行正则表达式匹配。
示例:使用compile函数生成的正则表达式对象
import re
pattern=re.compile(r'python',re.I) # 生成正则表达式对象,忽略大小写
result1=pattern.match('Python是一门流行的编程语言') # match函数匹配字符串开头的若干字符
result2=pattern.match('我喜欢学习Python!',5) # 指定起始位置
print('result1:',result1)
print('result2:',result2)
result1: <re.Match object; span=(0, 6), match='Python'>
result2: <re.Match object; span=(5, 11), match='Python'>
flags参数对应的匹配选项
re模块使用-mach(匹配字符串开头的)
用于对字符串开头的若干字符进行正则表达式的匹配,如果匹配成功,则返回一个Match对象,否则返回None。其语法格式为:
re.match(pattern,string,flags=0)
# pattern是要匹配的正则表达式;
# string要作正则表达式匹配的字符串;
# flags参数的含义与compile函数中的flags参数相同。
import re
result1=re.match(r'python','Python是一门流行的编程语言',re.I) # re.I 表示不区分大小写
result2=re.match(r'python','我喜欢学习Python',re.I) # 以python开头,未匹配到,所以返回None
result3=re.match(r'python',"'我喜欢学习Python,Python是一门流行的编程语言'",re.I|re.M) # 即便指定了re.M,re.match函数也只会对字符串开头的若干字符作匹配,而不对后面行的开头字符作匹配。
print('resule1:',result1)
print('resule2:',result2)
print('resule3:',result3)
# match函数返回的是一个Match对象,其中span是匹配的字符序列在字符串中的位置信息,而match中保存了匹配到的字符序列信息。
resule1: <re.Match object; span=(0, 6), match='Python'>
resule2: None
resule3: None
re模块使用- search(扫描整个字符串并返回第一个匹配结果)
对整个字符串进行扫描并返回第一个匹配的结果,匹配成功则返回一个Match对象,否则返回None。其语法格式为:
不同于re.match函数(只匹配字符串开头的若干字符),re.search函数可以对整个字符串从左向右扫描找到第一个匹配的字符序列。
re.search(pattern,string,flags=0) # 参数意思与match相同。
import re
result1=re.search(r'python','Python是一门流行的编程语言',re.I)
result2=re.search(r'python','我喜欢学习Python!',re.I)
result3=re.search(r'python','我喜欢学习Python,Python简单易用!',re.I)
result4=re.search(r'Java','我喜欢学习Python!',re.I)
print('result1:',result1)
print('result2:',result2)
print('result3:',result3)
print('result4:',result4)
result1: <re.Match object; span=(0, 6), match='Python'>
result2: <re.Match object; span=(5, 11), match='Python'>
result3: <re.Match object; span=(5, 11), match='Python'>
result4: None
同Pattern.match方法一样,也可以使用compile函数返回的正则表达式对象中的search方法实现re.search函数同样的功能,其语法格式为:
Pattern.search(string[,pos[,endpos]]) # 各参数含义与Pattern.match方法完全相同。
re模块使用-匹配对象
使用前面介绍的match、search函数时,匹配成功都会返回一个Match对象,失败时则返回None。这里我们看一下如何操作返回的Match对象。
例:根据Match对象判断是否匹配成功。
import re
result1=re.search(r'python','我喜欢学习Python!',re.I)
if result1: # 判断是否匹配成功
print('result1:',result1) # 匹配成功则输出返回的Match对象
result2=re.match(r'python','我喜欢学习Python!',re.I)
if result2: # 判断是否匹配成功
print('result2:',result2)
else:
print('result2匹配失败,返会None')
result1: <re.Match object; span=(5, 11), match='Python'>
result2匹配失败,返会None
注意:将Match对象作为判断条件时,其永远返回True,而None则返回False。
Match对象方法
这里我们仅学习group,groups,start和end这几种方法的使用。
例:Match对象中的方法使用示例。
import re
str='"sno:#1810101#,name:#李晓明#,age:#19#,major:#计算机#",sno:#1810102#,name:#马红#,age:#20#,major:#数学#'
rlt=re.search(r'name:#([\s\S]*?)#[\s\S]*?major:#([\s\S]*?)#',str,re.I) # *?每次匹配尽可能少的字符,\s匹配任一空白字符,\S匹配任一非空白字符(与小s\s相反)
if rlt: # 判断是否有匹配结果
print('匹配的整个字符串:',rlt.group())
print('name:%s,starpos:%d,endpos:%d'%(rlt.group(1),rlt.start(1),rlt.end(1)))
print('major:%s,startpost:%d,endpos:%d'%(rlt.group(2),rlt.start(2),rlt.end(2)))
print('所有分组匹配结果:',rlt.groups())
else:
print('未找到匹配信息')
匹配的整个字符串: name:#李晓明#,age:#19#,major:#计算机# # search方法仅返回整个字符串中匹配的第一个结果,
name:李晓明,starpos:21,endpos:24
major:计算机,startpost:42,endpos:45
所有分组匹配结果: ('李晓明', '计算机')
re模块使用-findall和finditer
用于在字符串中找到所有与正则表达式匹配的子串,其语法格式为:
re.findall(pattern,string,flags=0) # 各参数含义与re.match和re.search函数完全相。
re.finditer(pattern.striing,flags=0)
findall与finditer函数功能完全相同,唯一区别在于findall函数返回列表形式的结果,而finditer返回迭代器形式的结果。
import re
str='sno:#1810100#,name:#李晓明#,age:#19,major:#计算机#,sno:#1810102#,name:#马红#,age:#20#,major:#数学#'
rlt=re.findall(r'name:#([\s\S]*?)#[s\S]*?major:#([\s\S]*?)#',str,re.I)
rlts=re.finditer(r'name:#([\s\S]*?)#[s\S]*?major:#([\s\S]*?)#',str,re.I)
print(rlt)
print(rlts)
[('李晓明', '计算机'), ('马红', '数学')]
<callable_iterator object at 0x0000027081EB92D0>
例:finditer函数使用示例。
提示:re.finditer函数返回的迭代器中每一个元素都是一个Match对象。当匹配失败时,返回的迭代器中不包含任何元素。
import re
str='sno:#1810100#,name:#李晓明#,age:#19,major:#计算机#,sno:#1810102#,name:#马红#,age:#20#,major:#数学#'
rlt1=re.finditer(r'name:#([\s\S]*?)#[s\S]*?major:#([\s\S]*?)#',str,re.I)
rlt2=re.finditer(r'department:#([\s\S]*?)#',str,re.I)
print('rlt1:')
for r in rlt1:
print(r)
print('rlt2:')
for r in rlt2: # 匹配失败,返回的迭代器中不包含任何元素
print(r)
rlt1:
<re.Match object; span=(14, 44), match='name:#李晓明#,age:#19,major:#计算机#'>
<re.Match object; span=(59, 88), match='name:#马红#,age:#20#,major:#数学#'>
rlt2:
re模块使用-split(分割)
用于将字符串按与正则表达式匹配的子串分割,其语法格式如下:
re.split(patttern,string,maxsplit=0,flags=0)
# pattern、string、flags参数含义与re.match和re.search函数相同
# maxsplit是最大分割次数,默认为0表示不限制分割次数
例:re.split函数使用示例。
import re
str='sno:1810101,name:李晓明,age=19,major:计算机'
rlt=re.split(r'\W+',str) # 大写\W匹配不属于单词类字符的任意字符(这里匹配冒号);加号+匹配前一个模式1次或多次。
print(rlt)
['sno', '1810101', 'name', '李晓明', 'age', '19', 'major', '计算机']
re模块使用-sub(替换)
用于替换字符中与正则表达式匹配子串,其语法格式为:
re.sub(pattern,repl,string,count=0,flags=0)
# pattern,string,flags参数含义与re.match,re.search函数参数相同。
# repl是要将匹配子串替换成的字符串
# count是最大替换次数(默认为0,表示不限制替换次数)
例:re.sub函数使用示例。
import re
html='''<h3 class="c-title">
<a href="http://edu.people.com.cn/n1/2018/0905/c367001-30274290.html">
<em>南开大学</em>校长曹雪涛寄语新生</a></h3>>'''
content=re.sub(r'<[^<]*>',"",html) # 匹配由一对尖括号括起来的字符串,[^<]指定匹配的字符串不能包含左尖括号"<"
content=content.strip() # 去除字符串content两边的空白符
print('去除HTML标记后的内容为:',content)
去除HTML标记后的内容为: 南开大学校长曹雪涛寄语新生
re模块使用-subn(替换)
与re.sub函数功能完全相同,只是re.subn函数会以一个元组的形式同时返回替换匹配子串后得到的新字符串和替换的次数,其语法格式为:
re.subn(pattern,repl,string,count=0,flags=0) # 各参数含义与re.sub函数相同
import re
html='''<h3 class="c-title">
<a href="http://edu.people.com.cn/n1/2018/0905/c367001-30274290.html"><em>南开大学</em>校长曹雪涛寄语新生</a>
</h3>>'''
content=re.subn(r'<[^<]*>',"",html) # 匹配由一对尖括号括起来的字符串,[^<]指定匹配的字符串不能包含左尖括号"<"
# content=content.strip() # 去除字符串content两边的空白符
print('去除HTML标记后的内容为:',content)
去除HTML标记后的内容为: (' \n南开大学校长曹雪涛寄语新生\n', 6)