python中的转义就是通过转义符号\对字符进行字面意思和字符特殊定义(如果有的话)之间的转换,python中使用标准模块re进行字符串的正则表达式匹配时,需要特别注意转义符的使用,如果不了解正则表达式和字符串的转义符,那么很容易在使用正则表达式匹配时犯错。
在使用python的re模块进行正则匹配时,关于转义符需要注意的点有三处:1、正则表达式和字符串匹配的经历过程;2、字符串转义;3、正则表达式转义。
1、正则表达式和字符串匹配过程
当我们使用正则表达式字符串和被匹配字符串进行匹配时,实际上发生的过程如下图所示。即对于正则表达式字符串,其首先会经过python对字符串对象的转义,得到转以后的字符串,然后进一步的,re会使用转以后的字符串作为正则表达式pattern对象;当然进一步匹配的时候,正则表达式自身也有转义。对于被匹配的字符串,其也是经过字符串转义后再进入正则表达式匹配的。
因此,当我们要利用正则表达式进行匹配时,由于对于正则表达式的字符串转义不是我们所需要的,因此我们可以直接使用原生字符串(即以r作为开头表示的字符串,比如r'raw_string')来写正则表达式,这样可以避免字符串转义这个过程带来的非预期结果。具体的,我们看如下例子。
import re
re.findall(r'\\','\\')
[out]: ['\\'] #这个结果可以说明对于被匹配字符串,是经过字符串转以后匹配的,
#因为如果不转义直接匹配,那么被匹配的字符串为'\\',正则转义后的'\\'为'\',
#匹配后得到的结果将是['\','\'],其输出的格式将是['\\','\\'],因为'\'不是合法
#的输出对象,而是打印显示结果
re.findall('\\.','\\k')
[out]: []
re.findall('\\.','as.s')
[out]: ['.'] #这两个结果说明,对于正则表达式字符串,其是先经过字符串转义,再经过正则转义后
#进行匹配的;因为如果是直接正则转义,那么'\\.'匹配的是\加任意字符,所以对
#'\\k'的匹配结果应该是['\\k'],但实际结果是[];而实际上先经过字符串转义,得到\.,
#再经过正则转义,得到的就是原生的'.',因此对于'as.s'的匹配结果是['.']
2、字符串转义
对于字符串的转义,如果是未预定义的转义,或者说是一个单独的转义符\出现在字符串中,那么其会被认为是原生的\,但是为了保证显示的是\,会在对象输出的时候自动输出为\\。如下所示。
s = 'ca\lm'
s
[out]: 'ca\\lm'
3、正则转义
对于正则表达式的转义,如果\出现在了正则表达式中,但是其紧随的符号是一个未定义的转义,那么对于python3.6之前的版本,单个的转义符\会被自动忽略,但是在python3.6以及之后的版本,会发生报错,即不允许未定义的转义出现在正则表达式中,如果表达原生的\,需要\\进行转义以表达原生的\;这样报错的机制是为了给以后新加的转义定义留空间,并保持代码向后兼容,不然如果新的版本增加的新定义的转义且旧版本不报错,那么旧代码的正则表达式便不再适用了。
因此,无论是字符串还是正则表达式,对于转义符\的出现都要谨慎,对于原生反斜杠\的表示,记得进行\\转义。