前言
开始正式介绍Python正则表达式re模块中的内容。R&Python Data Science系列:数据处理(9)--Python之正则表达式re模块(一)搭建好了如何介绍re模块的框架,后面内容会按照正则表达式常用的语法、正则表达式编译函数compile()、re模块中RegexObject对象常用的方法、re模块中MatchObject实例的方法4部分往框架中填充内容。
5.2 Python之正则表达式re模块
Python中正则表达式使用re模块,re模块中的方法使用正则表达式来匹配字符串。
5.2.1 正则表达式的常用语法
工欲善其事,必先利其器。如何构造正则表达式?正则表达式像其他语言一样,有自己独有的语法,掌握其用法,就可以构造需要的正则表达式。常用的正则表达式语法有:
- 特殊字符
- 重复量词
- 分组与条件或
- 特殊字符
特殊字符为比较特殊的字符,与本身并不匹配,而表示一些特定的匹配,常用的特殊字符有:
语法 | 说明 | 正则表达式实例 | 匹配的字符串 | 匹配成功结果的字符串 |
---|---|---|---|---|
. | 匹配除换行符之外的任意字符 | r'Fla.' | 'Flash' | 'Flas' |
[] | 1、字符集[],匹配字符集中的一个字符,从左到右匹配直到匹配成功2、字符集[^]表示取反,即只要不是字符集内的字符都可以匹配成功3、"-"表示范围,当字符集有某种规则,例如[abcd],可以写成[a-d],[0-5][0-9] 将匹配从 00 到 59 的两位数字 4、所有特殊字符在[]中都失去原有的意思 | r'Fl[abc]' | 'Flash' | 'Fla' |
r'Fl[^bcf]' | 'Flash' | 'Fla' | ||
r'Fl[a-c]' | 'Flash' | 'Fla' | ||
r'Fl[ *]' | 'Fl*sh' | 'Fl*' | ||
A | 不在MULTILINE 模式下,A 等价于 ^ ;在 MULTILINE 模式:A 只是匹配字符串首,而 ^ 还可以匹配在换行符之后字符串的任何位置 | r'AFlash' | 'Flashs' | 'Flash' |
b | 匹配空字符串,匹配单词的词首和词尾,单词被定义为一个字母数字序列,因此词尾是用空白符或非字母数字符来表示的 | r'Flashb | 'Flashs' | '' |
r'Flashb | 'Flash ' | 'Flash' | ||
B | 与b相反,只在当前位置不在单词边界时候匹配 | r'Flashb | 'Flashs' | 'Flash' |
r'Flashb | 'Flash ' | '' | ||
d | 匹配单个数字字符0-9,等价于[0-9] | r'Flashd' | ‘Flash7a' | 'Flash7' |
D | 匹配非数字字符,等价于[^0-9] | r'FlashD' | ‘Flasha' | 'Flasha' |
s | 匹配任何空白字符,等价于 [ tnrfv] | r'Flashs' | ‘Flashn' | 'Flashn' |
S | 匹配任何非空白字符,等价于 [^ tnrfv] | r'FlashS' | ‘Flash7' | 'Flash7' |
w | 匹配任何字母数字字符,等价于 [a-zA-Z0-9] | r'Flashw' | ‘Flash7' | 'Flash7' |
W | 匹配任何非字母数字字符,等价 [^a-zA-Z0-9] | r'FlashW' | ‘Flash*' | 'Flash*' |
^ | 匹配行首,在 MULTILINE 模式里,匹配在换行符之后字符串的任何位置 | r'^Flash' | 'Flashs' | 'Flash' |
$ | 匹配行位,行尾被定义为要么是字符串尾,要么是一个换行字符后面的任何位置 | r's$' | 'Flashs' | 's' |
- 重复量词
如果想要匹配前一个字符n次,总不能把前一个字符写n次吧,正则表达式另一个强大的功能是可以指定重复的次数。
语法 | 说明 | 正则表达式实例 | 匹配的字符串 | 匹配成功结果的字符串 |
---|---|---|---|---|
* | 匹配前一字符0次到无限次(最大20亿次),贪婪匹配,尽量多的匹配 | r'Fla*' | 'Flaaa' | 'Flaaa' |
| 匹配前一字符1次到无限次(最大20亿次),贪婪匹配,尽量多的匹配 | r'Fla ' | 'Flaaa' | 'Flaaa' |
? | 匹配前一字符0次或者1次,贪婪匹配,尽量多的匹配 | r'Fla?' | 'Flaaa' | 'Fla' |
{m} | 匹配前一字符m次 | r'Fla{2}' | 'Flaaa' | 'Flaa' |
{m.n} | 匹配前一字符m次至n次,m是下限,n是上限,m和n可以省略,所以{m,}匹配前一字符m次至无限次,{,n}匹配前一字符0次至n次,贪婪匹配 | r'Fla{1,2}' | 'Flaaa' | 'Flaa' |
r'Fla{1,}' | 'Flaaa' | 'Flaaa' | ||
r'Fla{,2}' | 'Flaaa' | 'Flaa' | ||
*?和 ?和??和{m,n}? | 贪婪匹配变成非贪婪匹配,尽量少的匹配 | r'Fla*?' | 'Flaaa' | 'Fl' |
r'Fla ?' | 'Flaaa' | 'Fla' | ||
r'Fla??' | 'Flaaa' | 'Fl' | ||
r'Fla{1,2}?' | 'Flaaa' | 'Fla' | ||
r'Fla{1,}?' | 'Flaaa' | 'Fla' |
- 分组与条件或
上面特殊字符以及重复量词都是只能对前一个字符匹配,如果需要将前面几个字符作为一个整体(例如匹配以ab开头的字符串)或者匹配指定无规则字符中的一个(例如匹配以字母a或者b开头的字符串)。可以使用()来做分组,括弧内的字符为一个整体,使用|表示条件或,满足分支条件中的任意一种条件时,都会成功匹配。
语法 | 说明 | 正则表达式实例 | 匹配的字符串 | 匹配成功结果的字符串 |
---|---|---|---|---|
| | or的意思,优先级很低 | r'Fl|Wo' | 'FlaWork' | ['Fl', 'Wo'] |
() | 括弧中的字符为一个整体,可以使用量词或者| | r'(las)' | 'Flash' | las' |
r'(la|las)' | 'Flash' | la' |
注:以上正则表达式的语法,只列出一些常用到的语法,若没有列出的语法可以参考re--正则表达式操作文档(https://docs.python.org/zh-cn/3/library/re.html)
5.2.2 编译正则表达式
已了解正则表达式的常用语法,在Python中如何使用正则表达式呢?re模块提供了一个正则表达式引擎接口,可以将正则表达式编译成对象并用它们进行匹配。使用re.compile()将正则表达式编译成RegexObject对象,可以使用编译标志修改正则表达式的一些运行方式,如不区分大小写、多行匹配等。在re模块中标志有两种形式:全名与缩写,如DoTALL和S等价,默认情况下为re.UNICODE标志,多个标志通过|来指定,例如re.IGNORECASE|re.UNICODE。
常用的标志有:
标志 | 含义 |
---|---|
DOTALL或者S | 使 . 匹配包括换行在内的所有字符 |
IGNORECASE或者I | 使正则表达式忽略大小写 |
LOCALE或者L | 做本地化识别(locale-aware)匹配 |
MULTILINE或者M | 多行匹配,使每个^在每个回车后,每个$在每个回车前匹配 |
VERBOSE或者X | 该标志通过给予你更灵活的格式(如跨行、添加注释)以便你将正则表达式写得更易于理解。 |
UNICODE或者U | 特殊字符集 w, W, b, B, d, D, s, S 依赖于 Unicode 字符属性数据库 |
import rep = re.compile(r'Fla{1,}')p
import rep = re.compile(r'Fla{1,}')p.findall('Flaaa')
使用re.I标志,忽略大小写:
import rep = re.compile(r'Fla{1,}', re.I)p
import rep = re.compile(r'Fla{1,}', re.I)p.findall('FlAAA')
使用re.compile()将正则表达式编译成RegexObject,既然是对象,就有方法可以调用,RegexObject对象常用方法有match()、search()、findall()、finditer()、split()、sub()以及subn()。
RegexObject常用方法 | |
---|---|
方法/属性 | 作用 |
match() | 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none |
search() | 扫描整个字符串并返回第一个成功的匹配,没有匹配成功返回None |
findall() | 找到匹配成功的所有子串,并把它们作为一个列表返回,若没有匹配成功,返回空列表 |
finditer() | 找到匹配成功的所有子串,并把它们作为一个迭代器返回 |
split() | 将字符串在匹配成功的地方分割并生成一个列表, |
sub() | 找到匹配成功的所有子串,并将其用一个不同的字符串替换 |
subn() | 与 sub() 相同,但返回新的字符串和替换次数 |