正则表达式

正则表达式

正则表达式是一种用来匹配字符串的强有力武器。它的设计思想是用一种描述性的语言给字符串定义一个规则,凡是符合规则的字符串,就认为它匹配成功;否则,该字符串就是不合法的。

一、正则表达式常用符合

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']

这就完成了从贪婪到惰性的蜕变。

posted @ 2019-07-19 17:01  流浪代码  阅读(391)  评论(0编辑  收藏  举报