re.match方法
原型
re.match(pattern,string,flags = 0)
功能
尝试从字符串的起始位置匹配,该函数只匹配字符串开始的字符,如果开始的字符不符合正则表达式,匹配就会失败,函数返回None,如果匹配成功返还一个匹配对象。
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flag[可选] | 修饰符,用于控制正则表达式的匹配方式,如是否区分大小写、多行匹配等。可选内容见表1。 |
表1 修饰符
修饰符 | 描述 |
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w、 \W、 \b、\B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解 |
示例1
import re
string = 'Hello World Hi Python Hello China'
result0 = re.match('Hello\s(\w+)\sHi\s(.*?)\sHello\s(.*?)',string)
result1 = re.match('Hello\s(\w+)\sHi\s(.*?)\sHello\s(.*)',string)
result2 = re.match('Hi\sPython',string)
result3 = re.match('Hello\sWorld\sHi\s(\w+)',string)
print(result0.group())
print(result1)
print(result1.group())
print(result1.group(1),result1.group(2),result1.group(3))
print(result1.span())
print(result1.span(1),result1.span(2),result1.span(3))
print(result2)
print(result3.group(1))
运行结果
Hello World Hi Python Hello
<re.Match object; span=(0, 33), match='Hello World Hi Python Hello China'>
Hello World Hi Python Hello China
World Python China
(0, 33)
(6, 11) (15, 21) (28, 33)
None
Python
分析
1)本例我们想要把字符串string中的“World”、“Python”、“China”提取出来,此时可以将这三个字符串部分的正则表达式用()括起来,然后调用group()获取匹配的结果。如Line 3运行结果所示。
2)如果想要提取到的第一个()内的内容,则可调用group(1),同理,想要提取第二个、第三个()内的内容,则对应调用group(2)、group(3)即可。如Line 4运行结果所示。
3)此外想要知道提取到内容在原始字符串string中的具体位置,可调用span(),方法与group类似。如Line 6运行结果所示。
4)我们如果想要提取字符串string中的“Python”,运行结果却是None,表明匹配失败。这是为什么呢?原因其实很简单,re.match方法是从字符串起始位置开始匹配的,如果字符串的开头就不符合正则表达式的规则,则匹配失败。如Line 7运行结果所示。
5)将正则表达式“Hello\sPython”修改为“Hello\sWorld\sHello\s(\w+)”就能够匹配成功。如Line 8运行结果所示。
6)此外.*贪婪匹配,尽可能多的匹配字符,而.*?是非贪婪匹配,尽可能少的匹配字符。比较Line 1和Line 3,可以发现非贪婪匹配匹配到Hello World Hello Python Hello后的那个空格就结束匹配了,而贪婪匹配则匹配完全才结束。
贪婪匹配与非贪婪匹配
在做匹配的时候,字符串中间尽量使用非贪婪匹配,以免出现匹配结果缺失的情况。下面我们来看一个例子。
示例2
import re
string = 'Hello 123456 Python'
result1 = re.match('^He.*(\d+).*on$',string)
result2 = re.match('^He.*?(\d+).*on$',string)
print('result1',result1.group(1))
print('result2',result2.group(1))
运行结果
result1 6
result2 123456
分析
1)我们本想要提取原始字符串中的123456,但是却质得到了数字6,这是怎么回事?原因其实很简单,我们使用了贪婪匹配,正则表达式中.*后面是\d+,也就是至少一个数字,并没有指定具体多少个数字,因此.*就尽可能多的匹配字符,这里就把12345给匹配掉了,给\d+留下一个可满足条件的数字6,最后得到的内容自然只有数字6了。如Line 1运行结果所示。
2)事实上只需要把贪婪匹配改成非贪婪匹配,即把.*改成.*?就可以解决这个问题了。如Line 2运行结果所示。
但是如果要匹配的结果在字符串结尾,非贪婪匹配.*?可能就匹配不到或者匹配不完全我们所要的内容了,如示例1中的那样。
re.search方法
原型
re.search(pattern,string,flags = 0 )
功能
匹配整个字符串,直到找到一个匹配的对象,匹配结束后没找到匹配值才返回None。
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flag[可选] | 修饰符,用于控制正则表达式的匹配方式,如是否区分大小写、多行匹配等。可选内容见表1。 |
match方法只能从字符串初始位置开始匹配的弊端,现在通过一个例子来说明。
示例3
import re
string = 'Hello World Hi Python Hello China'
result1 = re.match('Hi\sPython',string)
result2 = re.search('Hi\sPython',string)
print(result1)
print(result2)
运行结果
None
<re.Match object; span=(12, 21), match='Hi Python'>
分析
在示例1中匹配失败的代码,只需要将match方法换成search方法就可以正常运行了。
re.findall方法
原型
re.findall(pattern,string,flags = 0 )
功能
前面介绍的re.search方法只能够返回匹配正则表达式的第一个内容,如果想要获取匹配正则表达式的所有内容,就需要使用re.findall方法了。该方法会搜索整个字符串,然后返回匹配正则表达式的所有内容。
参数 | 描述 |
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flag[可选] | 修饰符,用于控制正则表达式的匹配方式,如是否区分大小写、多行匹配等。可选内容见表1 |
注意
findall方法如果匹配成功,有返回结果的话,返回的是列表类型,因此需要遍历来依次获取内容。
re.sub方法
原型
sub(pattern,repl,string,count = 0,flags = 0 )
功能
替换字符串中的匹配项
参数 | 描述 |
pattern | 匹配的正则表达式 |
repl | 要替换的字符串,可以是一个字符串也可以是一个方法。当repl是一个字符串时,其中的任何反斜杠转义字符,都会被处理。当repl是一个方法时,这个方法应当只接收一个参数(match对象),并返回一个字符串用于替换(返回的字符串不能再引用分组) |
string | 要处理的字符串 |
count[可选] | 指定最多替换次数,默认为全部替换 |
flag[可选] | 修饰符 |
示例4
import re
string = '2018-12-13'
result = re.sub("\D",".",string)
print(result)
运行结果
2018.12.13
re.split方法
原型
split(pattern,string,maxsplit = 0,flags = 0 )
功能
根据指定的正则表达式分割字符串
示例5
import re
string = '2018*12*13'
result1 = re.split("\W+",string)
result2 = re.split("\*",string)
print('result1',result1)
print('result2',result2)
运行结果
result1 ['2018', '12', '13']
result2 ['2018', '12', '13']
re.compile方法
原型
compile(pattern,flags = 0 )
功能
将正则表达式编译成正则表达式对象,以便在后面的匹配中复用
参数 | 描述 |
pattern | 匹配的正则表达式 |
flag[可选] | 修饰符,用于控制正则表达式的匹配方式,如是否区分大小写、多行匹配等。可选内容见表1 |
示例6
import re
string1 = '2018-12-13 6:00'
string2 = '2018-12-13 12:00'
string3 = '2018-12-13 18:00'
pattern = re.compile('\d+:\d+')
result1 = re.sub(pattern,'',string1)
result2 = re.sub(pattern,'',string2)
result3 = re.sub(pattern,'',string3)
print('result1',result1)
print('result2',result2)
print('result3',result3)
运行结果
result1 2018-12-13
result2 2018-12-13
result3 2018-12-13
注意
compile()还可以传入修饰符,例如re.S等,这样在search(),findall()等方法中就不需要额外传了。所以compile()方法相当于给正则表达式做了一层封装,以便我们更好的复用。