Python re正则表达式模块的用法(非常详细)
正则表达式又称规则表达式,英文名为 Regular Expression,在代码中常简写为 regex、regexp 或 RE,是计算机科学中的一个概念。正则表达式通常用来检索、替换那些符合某个规则的文本。
正则表达式是对字符串和特殊字符操作的一种逻辑公式,用事先定义好的一些特定字符及这些特定字符的组合组成一个“规则字符串”。这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,描述在搜索文本时要匹配的一个或多个字符串。
正则表达式并不是 Python 独有的一部分。它拥有自己独特的语法及一个独立的处理引擎。在支持正则表达式的编程语言中,正则表达式的语法都是一样的,区别只在于不同的编程语言可实现的方式不同。
字符串是编程时经常涉及的一种数据结构,需要对字符串进行操作的编程场景不胜枚举。比如,注册一个网站时,需要用户设置的密码既要有大小写字母,还要有数字和特殊字符,此时就可以使用正则表达式来匹配用户输入的密码,判断其是否满足网站对合法密码的要求。
使用正则表达式判断用户密码的设置是否合法的方法为:
在正则表达式中,如果直接给出字符,就是精确匹配。由于使用 \d 可以匹配一个数字,使用 \w 可以匹配任意大写字母、小写字母和数字,因此 \d\d\d 可以匹配 \d、\w\w\w 可以匹配 Aai,\w\d\w 可以匹配 A1a。
由于点号(.)可以匹配任意字符,因此 a. 可以匹配 aA、ai、a# 等。
以上的匹配方法均是匹配单一字符。正则表达式有多种方法匹配变长字符,如:
例如:
Python 支持常用正则表达式的语法为:
需要注意的是,由于 Python 的字符串同样使用反斜杠(\)进行转义,因此使用 r 前缀来替代。
以下两种方式均表示字符串 abc\123:
使用 re 模块的一般步骤是先将正则表达式的字符串形式编译为 Pattern 实例,再使用 Pattern 实例处理文本并获得匹配结果(一个 Match 实例),最后使用 Match 实例获得信息,进行其他的操作。
当使用 Python 的正则表达式时,re 模块的内部实际上进行了两步操作:
编译的好处就是,如果一个正则表达式需要重复使用很多次,则可以预编译该正则表达式,在重复使用时就不需要编译这个步骤了,相当于省去了第一步,直接执行第二步进行匹配,提升了效率。
re 模块的流程代码为:
match 对象的属性如下:
在 Python 交互式解释器中的体验代码为:
在 Python 交互式解释器中的体验代码为:
Pattern 对象提供的属性有:
在 Python 交互式解释器中的体验代码为:
1) match 在前文中已经详细介绍过了。
2) search(string[,pos[,endpos]]|re.search(pattern,string,flags))
这个方法用于查找字符串中可以匹配成功的子串,从 string 的 pos 下标处开始尝试匹配 pattern:
pos 和 endpos 的默认值分别为 0 和 len(string)。re.search() 无法指定这两个参数。参数 flags 用于编译pattern时指定匹配模式。
比如,查看字符串中是否有'Python',代码为:
3) split(string[,maxsplit]|re.split(pattern,string,maxsplit)
按照能够匹配的子串将string分割后返回列表,maxsplit用于指定最大分割次数,若不指定,则全部分割。
比如,使用 split() 消除字母之间的空格,代码为:
也可以直接使用 re 调用。代码为:
消除逗号、分号,代码为:
4) findall(string[,pos[,endpos]])|re.findall(pattern,string[,flags])
搜索 string,并以列表的形式返回全部能够匹配的子串。
比如,返回字符串中的所有数字,代码为:
5) finditer(string[,pos[,endpos]]|re.finditer(pattern,string[,flags])
搜索 string,返回一个顺序访问每一个匹配结果的迭代器,代码为:
正则表达式是对字符串和特殊字符操作的一种逻辑公式,用事先定义好的一些特定字符及这些特定字符的组合组成一个“规则字符串”。这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,描述在搜索文本时要匹配的一个或多个字符串。
正则表达式语法
正则表达式是一种用来匹配字符串的强有力武器。它的设计思想是一种描述性的语言给字符串定义一个规则,凡是符合规则的字符串,就认为匹配成功;否则,该字符串就是不合法的。正则表达式并不是 Python 独有的一部分。它拥有自己独特的语法及一个独立的处理引擎。在支持正则表达式的编程语言中,正则表达式的语法都是一样的,区别只在于不同的编程语言可实现的方式不同。
字符串是编程时经常涉及的一种数据结构,需要对字符串进行操作的编程场景不胜枚举。比如,注册一个网站时,需要用户设置的密码既要有大小写字母,还要有数字和特殊字符,此时就可以使用正则表达式来匹配用户输入的密码,判断其是否满足网站对合法密码的要求。
使用正则表达式判断用户密码的设置是否合法的方法为:
- 创建一个匹配密码的正则表达式;
- 用该正则表达式去匹配用户输入的密码来判断是否合法。
在正则表达式中,如果直接给出字符,就是精确匹配。由于使用 \d 可以匹配一个数字,使用 \w 可以匹配任意大写字母、小写字母和数字,因此 \d\d\d 可以匹配 \d、\w\w\w 可以匹配 Aai,\w\d\w 可以匹配 A1a。
由于点号(.)可以匹配任意字符,因此 a. 可以匹配 aA、ai、a# 等。
以上的匹配方法均是匹配单一字符。正则表达式有多种方法匹配变长字符,如:
- 使用型号(*)匹配前一个字符无限次(包括 0 次);
- 使用加号(+)匹配前一个字符 1 次或无限次;
- 使用问号(?)匹配 0 个或 1 个字符;
- 使用 {n} 来匹配前一个字符 n 次。
例如:
- 'a*' 可以将 'aaaabcd' 中所有的 a 匹配出来,结果为 aaaa;
- 'a*b+' 可以将 'aaaabcd' 中所有的 a 和 b 匹配出来,结果为 aaaab;
- 'a?' 最多只匹配 'aaaabcd' 中的 a 一次,结果为 a;
- 'a{3}' 会匹配 'aaaabcd' 中的 a 三次,结果为 aaa。
Python 支持常用正则表达式的语法为:
语法 | 说明 |
---|---|
. | 匹配任意除换行符 (\n) 之外的字符 |
\ | 转义字符 |
\d | 数字,0-9 |
\s | 空白字符,如空格、\t、\n |
\w | 匹配所有大写字母,小写字母,数字 |
* | 匹配前一个字符 0 次或无限次 |
+ | 匹配前一个字符 1 次或无限次 |
? | 匹配前一个字符 0 次或 1 次 |
{n} | 匹配前一个字符 n 次 |
{n,} | 匹配前一个字符至少 n 次 |
{n,} | 匹配前一个字符 n 次到 m 次 |
s | 匹配被匹配对象的开头 |
Python re模块
Python 提供了 re 模块来支持所有正则表达式的功能。需要注意的是,由于 Python 的字符串同样使用反斜杠(\)进行转义,因此使用 r 前缀来替代。
以下两种方式均表示字符串 abc\123:
- 方式:str='abc\123';
- r 前缀方式:str=r'abc\123'。
使用 re 模块的一般步骤是先将正则表达式的字符串形式编译为 Pattern 实例,再使用 Pattern 实例处理文本并获得匹配结果(一个 Match 实例),最后使用 Match 实例获得信息,进行其他的操作。
当使用 Python 的正则表达式时,re 模块的内部实际上进行了两步操作:
- 编译正则表达式,如果正则表达式的字符串本身不合法,则会报错;
- 用编译后的正则表达式去匹配字符串。
编译的好处就是,如果一个正则表达式需要重复使用很多次,则可以预编译该正则表达式,在重复使用时就不需要编译这个步骤了,相当于省去了第一步,直接执行第二步进行匹配,提升了效率。
re 模块的流程代码为:
import re pattern = re.compile(r'\d+') m = pattern.match('123Python') if m: print(m.group()) else: print('failed')在流程代码中,首先导入 re 模块,然后通过 re.compile() 将字符串形式的正则表达式编译为 Pattern 对象,紧接着通过 pattern.match() 去匹配字符串 '123Python',如果匹配成功,则返回匹配结果;否则,提示匹配失败。
1、match对象
在流程代码中,第 4 行的 m 是一个 match 对象,是一次匹配的结果,包含很多关于此次匹配的信息,可以使用提供的属性或方法来获取这些信息。match 对象的属性如下:
- string:匹配时使用的文本;
- re:匹配时使用的 Pattern 对象;
- pos:文本中正则表达式开始搜索的索引,值与 Pattern.match() 和 Pattern.seach() 方法的同名参数相同;
- endpos:文本中正则表达式结束搜索的索引,值与 Pattern.match() 和 Pattern.seach() 方法的同名参数相同;
- lastindex:最后一个被捕获的分组在文本中索引,如果没有被捕获的分组,将为None。
- lastgroup:最后一个被捕获分组的别名,如果这个分组没有别名或者没有被捕获的分组,将为 None。
在 Python 交互式解释器中的体验代码为:
>>> import re >>> pattern = re.compile(r'(\d+)(\w+)(? P<loT>, *)') >>> m = pattern.match('123Python') >>> m.string '123Python' >>> m.pos 0 >>> m.endpos 9 >>> m.lastindex 3 >>> m.lastgroup 'IoT'match 对象的方法有:
- group([group, ...]):获得一个或多个分组截获的字符串,指定多个参数时将以元组形式返回;group() 可以使用编号也可以用别名;编号 0 代表整个匹配的子串;不填写参数时返回 group(0);没有截获字符串的组返回 None;截获了多次的组返回最后一次截获的子串。
- groups([default]):以元组形式返回全部分组截获的字符串,相当于调用group(1, 2, ...last),default 表示没有截获字符串的组以这个值替代,默认为 None。
- groupdict([default]):返回以有别名的组的别名为键,以该组截获的子串为值的字典,没有别名的组不包含在内,default 的含义同上。
- start([group]):返回指定的组截获的子串在 string 中的起始索引(子串第一个字符的索引),group 的默认值为 0。
- end([group]):返回指定的组截获的子串在 string 中的结束索引(子串最后一个字符的索引+1),group 的默认值为 0。
在 Python 交互式解释器中的体验代码为:
>>> import re >>> pattern = re.compile(r'(\d+)(\w+)(? P<loT>, *)') >>> m = pattern.match('123Python') >>> m.group(1) '123' >>> m.group(2) 'Python' >>> m.groups() ('123', 'Python', '') >>> m.groupdict() {'IoT':''} >>> m.start(2) 3 >>> m.end(1) 3
2、Pattern对象
Pattern 对象是一个编译好的正则表达式,必须使用 re.compile() 进行构造,提供了多个可读属性用于获取表达式的相关信息,以及一系列方法对文本进行匹配和查找。Pattern 对象提供的属性有:
- pattern:编译时使用的表达式字符串;
- flags:编译时使用的匹配模式,数字形式;
- groups:表达式中分组的数量;
- groupindex:以表达式中有别名的组的别名为键,以该组对应的编号为值的字典,没有别名的组不包含在内。
在 Python 交互式解释器中的体验代码为:
>>> import re >>> pattern = re.compile(r'(\d+)(\w+)(? P<loT>, *)') >>> pattern.pattern r'(\d+)(\w+)(? P<loT>, *)' >>> pattern.flags 32 >>> pattern.groups 3 >>> pattern.groupindex {'IoT': 3}除了属性,Pattern 对象还提供了多种方法。这些方法同样可以直接被 re 使用:
1) match 在前文中已经详细介绍过了。
2) search(string[,pos[,endpos]]|re.search(pattern,string,flags))
这个方法用于查找字符串中可以匹配成功的子串,从 string 的 pos 下标处开始尝试匹配 pattern:
- 如果 pattern 结束时仍可匹配,则返回一个 Match 对象;
- 若无法匹配,则将 pos 加 1 后重新尝试匹配,直到 pos=endpos 时仍无法匹配,则返回 None。
pos 和 endpos 的默认值分别为 0 和 len(string)。re.search() 无法指定这两个参数。参数 flags 用于编译pattern时指定匹配模式。
比如,查看字符串中是否有'Python',代码为:
import re pattern = re.compile(r'Python') m = pattern.search('Python-loT') if m: print(m.group()) else: print('failed')
3) split(string[,maxsplit]|re.split(pattern,string,maxsplit)
按照能够匹配的子串将string分割后返回列表,maxsplit用于指定最大分割次数,若不指定,则全部分割。
比如,使用 split() 消除字母之间的空格,代码为:
>>> import re >>> pattern = re.compile(r'\s+') >>> pattern.split('a b c d') ['a', 'b', 'c', 'd']
也可以直接使用 re 调用。代码为:
>>> re.split(r'\s+', 'a b c d') ['a', 'b', 'c', 'd']
消除逗号、分号,代码为:
>>> re.split(r'[,\s]', 'a,b,c,d') ['a', 'b', 'c', 'd']
4) findall(string[,pos[,endpos]])|re.findall(pattern,string[,flags])
搜索 string,并以列表的形式返回全部能够匹配的子串。
比如,返回字符串中的所有数字,代码为:
>>> re.findall(r'\d+', 'a1b2c3d4') ['1', '2', '3', '4']
5) finditer(string[,pos[,endpos]]|re.finditer(pattern,string[,flags])
搜索 string,返回一个顺序访问每一个匹配结果的迭代器,代码为:
import re pattern = re.compile(r'\d+') for m in pattern.finditer('a1b2c3d4'): print(m.group())运行结果为:
1
2
3
4
贪婪匹配
Python 的正则表达式默认是贪婪匹配的,也就是匹配尽可能多的字符。比如,匹配出数字 1001001000 后面的 0,代码为:>>> re.match(r'(\d+)(0*)$', '1001000').groups() ('1001000', '')由于 \d+ 采用贪婪匹配,把后面所有的 0 都匹配了,结果 o* 只能匹配到空字符串。因此必须让 \d+ 采用非贪婪匹配,也就是尽可能少匹配,才能把后面的 0 匹配出来,加个问号(?)就可以让 \d+ 采用非贪婪匹配,代码为:
>>> re.match(r'(\d+)(0*)$', '1001000').groups() ('1001', '000')