最近在学习python中的正则表达式,最开始对于匹配一个数字字符可以用'\d'来进行匹配,在调用re.compile()方法时,可以调用re.compile(r'\d'),即使用原始字符串传入,或者re.compile('\\d')传入(转义以后就是'\d')。但是后来突然发现使用re.compile('\d')时,结果也是一样的,接着就有了此文对转义字符及其在正则表达式的使用的学习记录。
所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示。而C中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了。下表给出了所有的转义字符:
转义字符 |
意义 |
ASCII码值(十进制) |
\a |
响铃(BEL) |
007 |
\b |
退格(BS) ,将当前位置移到前一列 |
008 |
\f |
换页(FF),将当前位置移到下页开头 |
012 |
\n |
换行(LF) ,将当前位置移到下一行开头 |
010 |
\r |
回车(CR) ,将当前位置移到本行开头 |
013 |
\t |
水平制表(HT) (跳到下一个TAB位置) |
009 |
\v |
垂直制表(VT) |
011 |
\\ |
代表一个反斜线字符''\' |
092 |
\' |
代表一个单引号(撇号)字符 |
039 |
\" |
代表一个双引号字符 |
034 |
\? | 代表一个问号 | 063 |
\0 |
空字符(NUL) |
000 |
\ooo |
1到3位八进制数所代表的任意字符 |
三位八进制 |
\xhh |
十六进制所代表的任意字符 |
十六进制 |
注意:
1. 区分,斜杠:"/" 与 反斜杠:"\" ,此处不可互换
2. \xhh 十六进制转义不限制字符个数 '\x000000000000F' == '\xF' [3]
(以上内容来自百度百科)
3、如果一个'\'后出现一个字符,且不是可以转义的字符,那么'\'及其后面的字符不会被转义
如果一个字符串使用了r来进行标志,那么这个字符串的所有字符字符将不会被转义,保持原始的字符,如:
#a=r'\n' 相当于 a='\\n'
print(r'\n'=='\\n') #结果为True
#说明:
# r'\n'表示两个字符('\'和'n')
# '\\n'也表示两个字符,'\\'转义后为'\',后面'n'不变
# 即转义只会转义一次
#a=r'\d' 相当于 a='\d'
print(r'\d'=='\d') #结果为True
#说明:
# \d不是转义字符所以二者一样
回归最初始的问题,为什么r'\d'和'\d'是一样的现在就可以解释了,因为二者就是表示的相同的字符串,均为'\d'
那么'\\d'呢?这么来看,首先,在字符串中'\\d'被解释为'\d',然后再re.compile()中被解释为数字的分类,所以r'\d','\d','\\d'在正则表达式中的意义是一样的,这里是\d不是转义字符,下面我们对一个转义字符进行分析。
对于r'\n','\\n','\n'又是如何呢?r'\n'在字符串中被解释为两个字符('\'和'n'),然后再re.compile()中又被解释一次,故实际在正则表达式中的意义为<匹配一个换行符>;'\\n'和r'\n'一样,在字符串中被解释为两个字符('\'和'n'),故在正则表达式中的意义也为<匹配一个换行符>;对于'\n',在字符串中的意义为'换行符',这个在re.compile()中不需要再被解释,故也是<匹配一个换行符的意思>
str1='123456\n123'
test1=re.compile(r'\n')
test2=re.compile('\\n')
test3=re.compile('\n')
print(test1.findall(str1),test2.findall(str1),test3.findall(str1))
#结果均可以匹配到换行符'\n'
上面的'\n'和'\d'在re.compile()中均可以被解释,我们再看看一个不可被解释的字符,如r'\p','\\p','\p'的结果是怎样的呢?结果均为报错,因为r'\p','\\p','\p'在字符串中的意思都是两个字符('\'和'p'),'\p'接着在re.compile()中不可被解释于是会报错(这和字符串中解释有一定区别,字符串中不能解释就不会解释)
①对于'\d',若需要不被解释为<匹配数字>,则传入re.compile()的字符串s在经过解释时不应该解释为'\d',而应该是一个'\'和一个'd',这样我们显然想到如果s为'\\d',那么s在re.compile()中就会被解释为'\d'(不会再被解释)。那么我们这么得到s呢?最简单的方法就是用原始字符串r'\\d'即表示'\\d',传入即可。如果不使用原始字符串,我们还可以使用'\\\d'和'\\\\d'来表示:'\\\d'中前两个'\'在字符串中被解释为'\',而后面的'\d'不变;'\\\\d'中依次两个'\'被解释为一个'\'故最终的结果也是'\\d',测试如下:
s='xx123\d456'
test1=re.compile(r'\\d')
test2=re.compile('\\\d')
test3=re.compile('\\\\d')
print(test1.findall(s),test2.findall(s),test3.findall(s))
#结果为['\\d'] ['\\d'] ['\\d']
#单个的'\'在字符串中表示为'\\'
②对于'\n'的情况与上述情况有一定的区别,首先被匹配的字符串里面需要有'\n'<不被解释为换行符>,这个我们可以用原始字符串或者用'\\n'表示。接着,对于s=r'\\n'以及s='\\\\n'在传入re.compile()以后的意义即'\\n',在re.compile()中被解释为一个'\'和一个'n';而对于s='\\\n',在字符串中前两个'\'会被解释为一个'\',后面的'\n'被解释为换行符,故在re.compile()中'\\\n'被解释为一个'\'和一个换行符,测试如下:
s='xx123\\n456'
test1=re.compile(r'\\n')
test2=re.compile('\\\n')
test3=re.compile('\\\\n')
print(test1.findall(s),test2.findall(s),test3.findall(s))
#结果为['\\n'] [] ['\\n']
#单个的'\'在字符串中表示为'\\'
#'\\\n'在字符串的意义为'\'+<换行符>
# 但是'\'在re.compile()中又会对后面的<换行符>进行转义--这里存在疑问
# 但是re.compile('\\\n')最终能匹配的结果为<换行符>
#若要匹配到'\'+<换行符>,可以进行如下操作
s='xx123\\\n456'
#s中\\\n被解释为'\'+<换行符>
test2=re.compile('\\\\\n')
#'\\\\\n'中的前四个'\'被解释为'\\'
#接着'\\'在re.compile()被解释为'\'
print(test2.findall(s))
#结果为['\\\n'],前面两个'\'表示一个'\',后面为一个换行符'\n'
③如果要匹配'\p'的话,其分析过程铜'\d',不再进行具体的说明。
仅作学习的记录,用词以及内容难免有不规范与纰漏,欢迎讨论与指正^_^