前五个比较重要
目录
1、re.match与re.search与re.findall的区别:
1.match()
传入匹配字符串以及正则表达式,从主串开头检测此正则表达式是否匹配字符串:若匹配则返回匹配成功的SRE_Match对象,若失败则返回None。 (注意从主串开始检测很容易混淆,其意味着:一旦开头不匹配就匹配失败)
实际上这个函数更适合检测一个正则表示式是不是正确哈。
测试
str = 'abc abcd abcde 213abc34'
print(re.match(r'[abc]{3}',str))
str = 'abc abcd abcde 213abc34' # 非开头
print(re.match(r'[123]{3}',str))
str = 'abc abcd abcde 213abc34'# 匹配失败
print(re.match(r'[a]{3}',str))
结果
<_sre.SRE_Match object; span=(0, 3), match='abc'>
None
None
SRE_Match对象
- match对象中包含了匹配结果的字符串,提取过程可以使用group()方法。
首先需要主串相应部分的正则表达式使用()括起来,match()以后,对返回值使用group()或者group(A),提取所有目标字符串,或者某一个字符串。
str = 'abc abcde 213abc34'
m1 = re.match(r'([abc]{3})\s[abcde]{5}(\s[123]{3}[abc]{3}[34]{2})',str)
print(m1)
print(m1.group())
print(m1.group(1))
print(m1.group(2))
结果
<_sre.SRE_Match object; span=(0, 18), match='abc abcde 213abc34'>
abc abcde 213abc34
abc
213abc34
- 使用span() 可以输出匹配范围。
2.search()
和match()很相似,在匹配时会扫描整个字符串,然后返回第一个成功的匹配的结果。
很遗憾,虽然比match方便很多,但是只能返回第一个匹配成功的字符串,
3.findall()
灯灯灯!findall满足了我们所有要求,返回所有匹配正则表示式的内容。
items = re.findall(r'\d*', page.text) # 注意这里r需要转换为字符串格式
4、compile()
编译正则表达式模式,返回一个对象的模式。
可以把那些常用的正则表达式编译成正则表达式对象,这样可以提高一点效率,当然也可以避免正则表达式过长的麻烦。
格式:
re.compile(pattern,flags=0)
pattern: 编译时用的表达式字符串。
flags 编译标志位,用于修改正则表达式的匹配方式,如:是否区分大小写,多行匹配等。常用的flags有:
5.sub()
使用正则表达式修改文本
import re
content = '45464dsffks3yhurh'
content = re.sub('\d+','',content)
print(content)
结果如下
dsffksyhurh
参数1: 正则
参数2:替换内容
参数3: 原字符串
参数4:替换个数。默认为0,表示每个匹配项都替换。
re.sub还允许使用函数对匹配项的替换进行复杂的处理。
如:re.sub(r'\s', lambda m: '[' + m.group(0) + ']', text, 0);将字符串中的空格' '替换为'[ ]'。
6. inditer()
搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。找到 RE 匹配的所有子串,并把它们作为一个迭代器返回。
格式:
re.finditer(pattern, string, flags=0)
iter = re.finditer(r'\d+','12 drumm44ers drumming, 11 ... 10 ...')
for i in iter:
print(i)
print(i.group())
print(i.span())
执行结果如下:
<_sre.SRE_Match object; span=(0, 2), match='12'>
12
(0, 2)
<_sre.SRE_Match object; span=(8, 10), match='44'>
44
(8, 10)
<_sre.SRE_Match object; span=(24, 26), match='11'>
11
(24, 26)
<_sre.SRE_Match object; span=(31, 33), match='10'>
10
(31, 33)
7、split()
按照能够匹配的子串将string分割后返回列表。
可以使用re.split来分割字符串,如:re.split(r'\s+', text);将字符串按空格分割成一个单词列表。
格式:
re.split(pattern, string[, maxsplit])
maxsplit用于指定最大分割次数,不指定将全部分割。
print(re.split('\d+','one1two2three3four4five5'))
执行结果如下:
['one', 'two', 'three', 'four', 'five', '']
四、一些注意点
1、re.match与re.search与re.findall的区别:
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
a=re.search('[\d]',"abc33").group()
print(a)
p=re.match('[\d]',"abc33")
print(p)
b=re.findall('[\d]',"abc33")
print(b)
执行结果:
3
None
['3', '3']
2、贪婪匹配与非贪婪匹配
*?,+?,??,{m,n}? 前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配
a = re.findall(r"a(\d+?)",'a23b')
print(a)
b = re.findall(r"a(\d+)",'a23b')
print(b)
执行结果:
['2']
['23']
a = re.match('<(.*)>','<H1>title<H1>').group()
print(a)
b = re.match('<(.*?)>','<H1>title<H1>').group()
print(b)
执行结果:
<H1>title<H1>
<H1>
a = re.findall(r"a(\d+)b",'a3333b')
print(a)
b = re.findall(r"a(\d+?)b",'a3333b')
print(b)
执行结果如下:
['3333']
['3333']
#######################
这里需要注意的是如果前后均有限定条件的时候,就不存在什么贪婪模式了,非匹配模式失效。
3、用flags时遇到的小坑
print(re.split('a','1A1a2A3',re.I))#输出结果并未能区分大小写
这是因为re.split(pattern,string,maxsplit,flags)默认是四个参数,当我们传入的三个参数的时候,系统会默认re.I是第三个参数,所以就没起作用。如果想让这里的re.I起作用,写成flags=re.I即可。