Reference:https://www.runoob.com/python/python-reg-expressions.html
正则表达式是一个特殊的字符序列,能帮助检查一个字符串是否与某种模式匹配。python自1.5版本起增加了re模块,re模块使python语言拥有全部的正则表达式功能。
compile函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象,该独享拥有一系列方法用于正则表达式匹配和替换。
re模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串作为它们的第一个参数。
目录
re.match()函数
re.match尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的的话,match()就返回none。
函数语法:
re.match(pattern, string, flags=0)
函数参数说明:
pattern:匹配的正则表达式
string:要匹配的字符串
flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等。(Reference:https://www.runoob.com/python/python-reg-expressions.html#flags)
匹配成功re.match方法返回一个匹配的对象,否则返回None
可以使用group(num)或groups()匹配对象函数来获取匹配表达式
匹配对象方法:
group(num=0):匹配整个表达式的字符串,group()可以一次输入多个组号,在这种情况下它将返回一个包含那些组对应值的元组
groups():返回一个包含所有小组字符串的元组,从1到所含的小组号
这些怎么理解,没有太理解意思,需要进一步尝试,从以下几个示例看起来,.group(0)用来返回整个字符串(是否是匹配到的整个),groups()用来返回匹配中正则表达式要求()中的一个包含多个的列表,看起来默认使用span就可以了,另外区别于re.find(),re.match()必须是从头开始匹配
如果需要定位的话使用matchObj中的span()方法
>>> import re
>>> strr = 'www.baidu.com'
>>> matchObj = re.match('www', 'www.baidu.com')
>>> print(matchObj)
<re.Match object; span=(0, 3), match='www'>
>>> print(matchObj.span())
(0, 3)
>>> print(matchObj.span()[0])
0
>>> print(matchObj.span()[1])
3
>>> print(re.match('com', 'www.runoob.com'))
None
>>> import re
>>> strr = 'Cats are smarter than dogs'
>>> matchObj = re.match(r'(.*) are (.*?) .*', strr, re.M|re.I)
>>> print(matchObj.groups())
('Cats', 'smarter')
>>> print(matchObj.group())
Cats are smarter than dogs
>>> print(matchObj.group(1))
Cats
>>> print(matchObj.group(2))
smarter
>>> print(matchObj.group(3))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: no such group
>>> matchObj = re.match(r'(.*) are (.*?) (.*)', strr, re.M|re.I)
>>> print(matchObj.groups())
('Cats', 'smarter', 'than dogs')
>>> print(matchObj.group())
Cats are smarter than dogs
>>> print(matchObj.group(1))
Cats
>>> print(matchObj.group(2))
smarter
>>> print(matchObj.group(3))
than dogs
re.search()函数
re.search()扫描整个字符串(而不仅仅只是必须从头开始),并返回第一个成功的匹配。
函数语法:
re.search(pattern, string, flags=0)
函数参数说明:
pattern:匹配的正则表达式
string:要匹配的字符串
flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等。
匹配成功re.search()方法返回一个匹配的对象,否则返回None
我们可以使用group(num) 或 groups()匹配对象函数来获取匹配表达式(获取匹配到的字符是哪些),这里的group和groups匹配对象方法和之前一样
实例如下:
>>> import re
>>> line = 'www.baidu.com'
>>> print(re.match('com', line).span())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'span'
>>> print(re.search('com', line).span())
(10, 13)
re.match()和re.search()的区别
re.match()只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search()匹配整个字符串,直到找到一个匹配。
检索和替换-re.sub()函数
python的re模块提供了re.sub()用于替换字符串中的匹配项。
语法:
re.sub(pattern, repl, string, count=0, flags=0)
参数:
pattern:正则中的模式字符串
repl:替换的字符串,也可为一个函数
string:要被查找替换的原始字符串
count:模式匹配后替换的最大次数,默认为0表示替换所有的匹配
注:这个函数不会改变原有的字符串,而会return会进行改变后的字符串
注:下边示例中的\d代表匹配所有数字字符,\D相当于是其反过来,匹配所有非数字字符
>>> import re
>>> phone = '4008-517-517 # 这是麦当劳外卖的电话号码'
>>> temp1 = re.sub('#.*$', '', phone)
>>> print(temp1)
4008-517-517
>>> print(phone)
4008-517-517 # 这是麦当劳外卖的电话号码
>>> temp2 = re.sub(r'\D', '', phone)
>>> print(temp2)
4008517517
>>> temp3 = re.sub(r'\d', '', phone)
>>> print(temp3)
-- # 这是麦当劳外卖的电话号码
语法中的repl参数(replace)是一个函数,用于对匹配到的字符串进行该对应函数的处理,这里也可以不放函数,就是单纯的放一个字符串也可以(但是感觉对于group,groups的理解还不是很到位)
>>> phone
'4008-517-517 # 这是麦当劳外卖的电话号码'
>>> temptemp = re.sub('(?P<num>\d+)', lambda x:str(int(x.group('num'))+2), phone)
>>> print(temptemp)
4010-519-519 # 这是麦当劳外卖的电话号码
编译正则表达式-re.compile()函数
.compile()函数英语编译正则表达式,生成一个正则表达式的Pattern对象,供match()和search()这两个函数使用,语法格式为
re.compile(pattern, flags)
参数及解释:
pattern:一个字符串形式的正则表达式
flags:可选参数,表示匹配模式,比如忽略大小写,多行模式等,具体参数如下
>>> import re
>>> pattern = re.compile(r'\d+')
>>> temp1 = pattern.match('one1two2threefour34')
>>> print(temp1)
None
>>> temp2 = pattern.findall('one1two2threefour34')
>>> print(temp2)
['1', '2', '34']
>>> pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I) # re.I忽略大小写
>>> temp2 = pattern.findall("Hello World this is a TEST CASe")
>>> print(temp2)
[('Hello', 'World'), ('this', 'is'), ('a', 'TEST')]
注:从上例中可以看出如果是以这种形式匹配,不会进行重复,而是一句话顺着扫,重复指的是匹配不到“World this”
找到所有匹配并返回列表-findall()函数
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
语法格式
pattern.findall(string, pos, endpos)
参数说明解释:
string:待匹配的字符串
pos:可选参数,指定字符串的起始位置,默认0
endpos:可选参数,指定字符串的结束为止,默认为字符串的长度
找到所有匹配并返回迭代器-finditer()函数
和findall类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回,另外注明finditer从re开始调用,findall貌似是从pattern对象开始调用的
re.finditer(pattern, string, flags=0)
>>> import re
>>>
>>> it = re.finditer(r"\d+","12a32bc43jf3")
>>> for item in it:
... print(item)
...
<re.Match object; span=(0, 2), match='12'>
<re.Match object; span=(3, 5), match='32'>
<re.Match object; span=(7, 9), match='43'>
<re.Match object; span=(11, 12), match='3'>
其中每个item这个对返回值对象可以通过span() group()等方法进行调用
匹配子串并切分返回列表-re.split()函数
split方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:
re.split(pattern, string, maxsplit=0, flags=0)
参数说明:
pattern:匹配的正则表达式
string:要匹配的字符串
maxsplit:分隔次数,maxsplit=1分隔一次,默认为0表示不限制次数
flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
个人感觉和直接调用str的split方法的区别在于,这个可以更好的使用正则表达式进行匹配?
其它具体内容可进一步参考Reference
实例解析1
首先由于正则表达式是一个字符串,前边的一个r表示字符串为非转义的原始字符串,让编译器忽略反斜杠,也就是忽略转义字符。
(.*)第一个匹配分组,.*代表匹配换行符之外的所有字符
(.*?)第二个匹配分组,.*?后边多了一个问号,代表非贪婪模式,也就是说只匹配符合条件的最少字符
后边的一个.*没有括号包围,所以不是分组,匹配效果和第一个一样,但是不计入匹配结果中。(这里的用处在哪里,还是说就是为了直接匹配)
matchObj.group()等同于matchObj.group(0),表示匹配到的完整文本字符
matchObj.group(1)得到第一组匹配结果,也就是(.*)匹配到的
matchObj.group(2)得到第二组匹配结果,也就是(.*?)匹配到的
因为匹配结果只有两组,所以填3时会报错
实例解析2
在线正则表达式