2.3 正则表达式

一、匹配

1.元字符:不与自身匹配,会和一些其他字符匹配

.   ^   $   *   +   ?   []   {}   \   |   ()

2.元字符 ‘[ ]’,用于制定一个字符类(所想指定的字符集)

[abc] #可以匹配字符‘a’‘b’‘c’中的任意一个字符
[a-c] #与上面的有相同功能

元字符在字符类中不起作用

[abc$] #其中$只代指‘$’这个字符,不具备其他意义

3.元字符‘ () ’,分组,可以使用group()方法来索引

import re

p = re.compile('ab')
m = p.match('ab')
m.group(0)
'ab'

group()默认0为匹配字符串

import re

p = re.compile('(a(b)c)d')
m = p.match('abcd')
m.group(0)
'abcd'
m.group(1)
'abc'
m.group(2)
'b'
m.group(0,1,2)
('abcd','abc','b')

分组使得很容易从匹配到的字符串中提取数据,也可以很容易进行组合以元组的形式输出

如何逆向引用?

4.元字符 ‘ ^ ’,在‘[ ]’内时匹配除此之外的任意字符

还可以用于只匹配字符串的开头,如果使用了标志M,则会匹配每一行字符串的开头

5.转义字符 ‘\’,用于取消元字符的特殊意义

但是一些特殊组合表示特定的意义,如

6.元字符 ‘ . ’,可以匹配除了换行符之外的所有字符

7.元字符‘ | ’,‘或’操作符,如‘ (A|B) ’,则会匹配A或B,常和分组符号‘()’一起用

8.元字符‘ $ ’,与‘ ^ ’刚好相反,只匹配行尾的字符串,或者任何后面紧跟着一个换行符的位置。

9.零宽界定符‘ \b ’,没有宽度,用于匹配单词的开头和结尾

10.与‘ \b ’类似,‘ \B ’另一个零宽界定符,只有不是开头和结尾才符合

二、重复

指定某一部分的重复次数

1.元字符‘ * ’,‘贪婪’的重复(Greedy),可以重复零个或任意多个字符

2.元字符‘ + ’,至少有一个

3.元字符‘ ? ’,有一个或零个

4.重复限定符{m,n},表示至少重复m次,最多不能超过n次,省略m,则默认下限为0,省略n,则默认无上限或上限为无穷

前面三种都可以有{m.n}的格式来表示

三、使用

re模块:一个被Python包含的C扩展模块,就像socket模块

1.正则表达式被便以为正则表达式对象,可以用来做模式匹配或字符串替换

2.反斜杠的问题,为了避免反斜杠的重复,使用python中原始字符串来简化

3.正则表达式对象的方法和属性

  • match() 判断从字符串开头是否匹配正则表达式

如果可以匹配的话,会回复一个match对象

match对象的方法和属性

  • 模块中也有match(), search(), sub()函数等

实际中可以用正则表达式对象本身的方法,也可以使用模块的中的函数,当调用函数时,第一个参数就是正则表达式,之后该函数会自动创建一个正则表达式对象。两者使用时如何选择,之后再了解。

4.编译标志

四、无捕获组和命名组、前向界定符

当我们捕获一个字符串时,其中有我们感兴趣的部分,也有不是很在意的部分。通过正则表达式中的分组功能,我们可以定义字符串中的无捕获组和命名组,来区分字符串中的信息。

  • 无捕获组:格式为‘ (? = REs) ’,REs为正则表达式,只能从组1开始。

  • 命名组:格式为‘ (?P<name>) ’,命名组的作用是将特别关心的信息命名,之后调用的时候,就不用难记的序号,而是用名字直接引用。

重要的是,逆向引用中也可以使用命名组。

仍然不会逆向引用。。。

前向界定符,又称为‘前向断言’,是一种不会引起正则表达式引擎移动的匹配模式,只会返回匹配结果,有肯定和否定两种。

  • 肯定前向界定符:格式为' (?REs) ',在当前位置匹配成功时,返回成功,否则失败。

  • 否定前向定界符:格式为' (?!REs) ',在当前位置匹配不成功时,返回成功,否则失败。

前向界定符可以用来简化很多情况,比如当匹配模式中想要排除某种情况,直接用‘ ^ ’的形式,可能会非常复杂,但是使用前向界定符直接判断前方是否有那种情况,如果有则失败,没有则继续匹配。

五、修改字符串

除了搜索特定字符串之外,正则表达式还可以动态地修改字符串,主要操作有切片,替换等。

1.切片 split()

  • 正则表达式对象中的方法,可以设置参数来控制切片的数量。

有时我们对于分隔符也比较感兴趣,这时使用捕获括号,就能将分隔符作为列表的元素返回

  • 模块中的函数 re.split(REs, string, [maxstep = 0] )

2.替换 sub() 和subn()

  • 正则表达式中的方法

subn()的作用类似,但是会返回一个包括新字符串和替换次数的元组

空匹配只有在紧邻的前面一个没有被替换时才会替换

如果用来替换的字符串中有反斜杠,都会被处理。如‘ \n’ 会被作为换行符。逆向引用也可以被使用。

3.re.findall(pattern, string[,flags]),搜寻string,以列表的形式返回全部能匹配的字符串

4.re.finditer(pattern, string[,flags]),搜寻string,返回一个顺序访问每一个匹配结果(match对象)的迭代器

六、小结

正则表达式' \(1)s ', ' \(2)s ', r' \(1)s '都是代表着空白字符,而只有r' \(2)s '才能匹配字符串中的' \(1)s ',而返回的匹配字符串是' \(2)s '。

这个说明想要不使用原始字符串匹配‘ \(1)s ’,就必须要用' \(4)s ',因为目标字符串看似是‘ \(1)s ’,其实是' \(2)s '。从' \(4) s '到r' \(2)s ',这就是原始字符的作用。另外,r'\(1)s' 就等于' \(2)s',因此它代表的也是' \(1)s ',这时r就显得多余了。

七、补充

1、?匹配前面一个表达式0次或多次,如果紧跟在量词 * + {} ?后 量词为非贪婪,匹配尽量少的字符。例如,对 "123abc" 应用 /\d+/ 将会返回 "123",如果使用 /\d+?/,那么就只会匹配到 "1"。

Last updated

Was this helpful?