盒子
盒子

Python正则表达式(二)

正则描述符

*描述符

正则表达式的重复运算符是*,例如:

1
α*: 匹配模式α任意多次

因此执行re.split('[ ,]*', 'abbaabbbadbbdbaabcaab')得到的结果为[‘’, ‘bb’, ‘bbb’, ‘dbbdb’, ‘bc’, ‘b’]。

?描述符

?为可选描述符。
比如α?表示与α匹配0次或1次,即匹配空串或者α模式串。
例如:表示整数的一种正则表达形式为-?\d+,其匹配正数、负数和0。

{n}描述符

{n}为重复次数描述符。
比如α{5}表示与α模式串重复匹配5次。
例如:匹配北京固话的正则表达式的一种表示形式为(010-)?[2-9][0-9]{7}。该正则与010-开头,随后一位数字为2到9,之后7位0到9的数字的字符串匹配。

{m,n}描述符

{m,n}为重复次数范围描述符。
比如α{2,4}表示重复匹配α模式串2到4次,包括2次和4次。
重复范围描述符中的m和n可以省略,例如α{,n}等价与α{0,n},而α{m,}等价于α{m,infinity}。

|描述符

|为选择描述符,其与两种或多种情况之一匹配。
比如α|β表示与α或者β之一的模式串匹配。

首位描述符

  • 行首描述符:以’^’开头的模式串,与目标字符串一行的前缀子串匹配。
  • 行尾描述符:以’$’结尾的模式串,与目标字符串一行的后缀子串匹配。

例如:

1
2
re.search('^for', 'This is for you')       #匹配结果为None。
re.search('^for', 'This is \nfor you') #匹配成功。

1
2
re.search('book$', 'I have many books')    #匹配结果为None。
re.search('book$', 'This is a book') #匹配成功。

贪婪匹配和非贪婪匹配

考虑如下匹配模式:

1
re.match('ab*', 'abbbbbbc')

对于其中的匹配模式ab*,匹配字符串中的ababbbbbb均可与其匹配,那么这个时候该匹配哪一种字符串呢?正则表达式提供了两种可能的匹配方案:

  • 贪婪匹配: 匹配目标字符串中尽可能长的子串
  • 非贪婪匹配: 匹配目标字符串尽可能短的子串

其中非贪婪匹配又称吝啬匹配,正则表达式规定*运算符做贪婪匹配,因此上述ab*将会匹配abbbbbb
*+?{m,n}均采取贪婪匹配规则,若要采用非贪婪匹配规则,可以使用非贪婪匹配描述符,*?+???{m,n}?均为非贪婪描述符,即在上述各贪婪描述符后加一个?,其语义与上述几个描述符对应,但都采取非贪婪匹配原则。

Python与正则表达式

Python中使用正则表达式进行模式匹配时,匹配成功时会返回一个match对象,其中记录着匹配成功的相关信息。
不妨设我们匹配成功之后得到的match对象记为mat。

常用函数

mat.group()

group()函数用于取得匹配成功的子串。

mat.start()

start()函数获得匹配成功的目标子串起始位置的下标。

mat.end()

end()函数获得匹配成功的目标子串结束位置的下标。

mat.span()

span()函数获得匹配成功的目标子串的位置区间,即mat.span() = mat.start(), mat.end()

正则模式的group

正则表达式的一个重要概念是组。圆括号括起来的一段模式串代表一个组,在一次成功的匹配中,每一个组匹配成功的字符串将从1开始编号,组0表示与整个模式匹配的字符串,我们可以通过mat.group(n)来获得组n的匹配字符串。

其他常用匹配操作

正则表达式还有一些其他的常用匹配操作,如下:

1
2
3
4
5
6
7
8
9
10
11
# 生成一个正则表达式对象,可重复使用。
re.compile(pattern)

# 若string与pattern模式匹配成功返回匹配对象,否则返回None
re.fulmatch(pattern, string, flags=0)

# 将匹配结果以迭代器的形式返回,否则返回None
re.finditer(pattern, string, flags=0)

# 将string中与pattern模式匹配的部分用repl替换
re.sub(pattern, repl, string, count=0, flags=0)