正则表达式
正则表达式 |
正则表达式是一种用来匹配字符串的强有力武器。它的设计思想是用一种描述性的语言给字符串定义一个规则,凡是符合规则的字符串,就认为它匹配成功;否则,该字符串就是不合法的。
一、正则表达式常用符合
1.一般字符
正则表达式的一般字符有3个,如下表所示:
字符 | 含义 |
. | 匹配任意当个字符(不包括换行符\n) |
\ | 转义字符 |
[...] | 字符集。对应字符集中的任意字符 |
(1)“.”字符为匹配任意单个字符。例如,a.b可以的匹配结果为abc、aic、a&c等,但不包括换行符。
(2)“\”字符为转义字符,可以把字符改变为原来的意思。例如“.”字符是匹配任意的单个字符,但有时不需要这个功能,只想让它表示一个点,这时就可以使用“\.”,就能匹配为“.”了。
(3)[...]为字符集,相当于在中括号中任选一个。例如a[bcd],匹配的结果为ab、ac、ad。
2.预定义字符集
正则表达式预定义字符集有6个,如下表所示:
预定义字符集 | 含义 |
\d | 匹配一个数字字符。等价于[0-9] |
\D | 匹配一个非数字字符。等价于[^0-9] |
\s | 匹配任何空白字符,包括空格、制表符、换行符等。等价于[\f\n\r\t\v] |
\S | 匹配任何非空白字符。等价于[^\f\n\r\t\v] |
\w | 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]' |
\W | 匹配任何非单词字符。等价于'[^A-Za-z0-9_]' |
3.数量词
正则表达式中的数量词如下表所示:
数量词 | 含义 |
* | 匹配前一个字符0或无限次 |
+ | 匹配前一个字符1或无限次 |
? | 匹配前一个字符0或1次 |
{m} | 匹配前一个字符m次 |
{m,n} | 匹配前一个字符m至n次 |
(1)“*”数量词匹配前一个字符0或无限次。例如,ab*c匹配ac、abc、abbc等。
(2)“+”与“*”很类似,只是至少匹配前一个字符一次。例如,ab+c匹配abc、abbc等。但不能匹配到ac。
(3)“?”数量词匹配前一个字符0或1次。例如,ab?c匹配ac和abc。
(4)“{m}”数量词匹配前一个字符m次。例如,ab{3}c匹配abbbc。
(5)“{m,n}”数量词匹配前一个字符m至n次。例如,ab{1,3}c匹配abc、abbc、abbbc。
4.边界匹配
正则表达式的边界匹配的符号如下表所示:
边界匹配 | 含义 |
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
(1)“^”匹配字符串的开头。例如,^abc匹配abc开头的字符串。
(2)“$”匹配字符串的结尾。例如,abs$匹配abc结尾的字符串。
5.分组
正则表达式的分组的符合如下表所示:
分组 | 含义 |
() | 分组 |
(?P<name>) | 命名分组 |
二、re模块及其方法
re模块是Python语言拥有全部的正则表达式功能。
在Python中,想要使用正则表达式,第一步先需要引入re模块。re模块为Python中的内置模块,所以无须单独安装,直接导入即可,具体代码如下:
import re #引入re模块
在re模块中提供了一系列方法对文本进行匹配查找,下面进行详细的介绍。
1.search()方法
search():用于在字符串内查找匹配,只要找到第一个匹配然后返回即可,如果字符串没有匹配,就返回None。代码如下所示:
import re print(re.search('\d+','one1two2three3'))
执行结果为:
<re.Match object; span=(3, 4), match='1'>
可以看出,search()方法返回的是正则表达式对象,通过正则表达式匹配到了“1”这个字符串,可以通过下面的代码返回匹配到的字符串:
import re print(re.search('\d+','one1two2three3').group())
2.findall()方法
findall():用于遍历匹配,可以获取字符串中所有匹配的字符串,返回一个列表。代码如下所示:
import re print(re.findall('\d+','one1two2three3'))
执行结果为:
['1', '2', '3']
findall()方法是对于整个字符串进行匹配,最后将所有匹配成功项以列表形式进行返回输出['1','2','3'].
3.match()方法
match():只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,返回None。代码如下所示:
import re print(re.match('\d+','one1two2three3')) print(re.match('\d+','1one2two3three')) print(re.match('\d+','1one2two3three').group())
执行结果为:
None <re.Match object; span=(0, 1), match='1'> 1
4.split()方法
split():安照能够匹配的字符对字符串分割后返回列表。代码如下所示:
import re print(re.split('[\d]','one1two2three3')) print(re.split('[\d]','1one2two3three'))
执行结果为:
['one', 'two', 'three', ''] ['', 'one', 'two', 'three']
上述代码通过正则表达式对字符串进行分割,[\d]表示按照数字字符中的任意字符进行分割,当然也可以指定分割次数,默认全部分割。
5.sub()方法
sub():使用re替换字符串中每一个匹配的字串返回替换后的字符串。代码如下所示:
import re print(re.sub('[\d]','a','one1two2three3'))
执行结果为:
oneatwoathreea
上述代码使用sub()方法将正则匹配成功的数字项替换为a。
6.compile()方法
compile():返回的正则表达式对象所支持的方法。代码如下所示:
import re ret = re.compile('\d+') print(ret.findall('a1b22c3'))
执行结果为:
['1', '22', '3']
三、贪婪模式和惰性模式
贪婪模式,光听名字就知道是一个贪婪的家伙,就是尽可能多地匹配。而惰性匹配就是尽可能少的匹配。
在Python中,默认是贪婪模式。下面我们就对一段代码进行分析:
import re print(re.findall('\d+','a1b222c33'))
执行结果为:
['1', '222', '33']
有没有疑问输出结果为什么是['1','222','33']而不是['1','2','2','2','3','3']?这个是正则表达式中的贪婪模式,就是尽可能多地匹配。
如果不想要贪婪匹配,需要让“\d+”采用惰性匹配(尽可能少地匹配),在“\d+”后面加一个?即可,代码如下所示:
import re print(re.findall('\d+?','a1b222c33'))
执行结果为:
['1', '2', '2', '2', '3', '3']
这就完成了从贪婪到惰性的蜕变。