Python正则表达式匹配反斜杠

在学习Python正则式的过程中,有一个问题一直困扰我,如何去匹配一个反斜杠(即“\”)?

一、引入

在学习了Python特殊字符和原始字符串之后,我觉得答案应该是这样的:
1)普通字符串:’\’
2)原始字符串:r’’
但事实上在提取诸如“3\8”反斜杠之前的数字时,我屡次碰壁,始终得不到结果。最终发现自己理解错了,原来原始字符串和“正则转义”没有一点关系;下面详细谈一谈。

二、字符串转义

反斜杠,在Python中比较特殊,就是它可以用来构成一些特殊字符,比如“\n”表示换行,“\t”表示制表符。下面是使用“\n”的一行代码:
print (‘Hello\World\nPython’ )
结果为:
“Hello\World
Python“
可以看到其中的“\n”已转义为换行符,而“\W”没有发生转义,原因是“\W”在“字符串转义”中并不对应着特殊字符,没有特殊含义。

如果现在要求变了,要求不对“\n”转义为换行,而是原封不动输出为“Hello\World\nPython”,该怎么办呢?

1)可以这样写“Hello\World\nPython”,这样输出的时候,“字符串转义”会把“\”转义为“\”;
2)也可使用另一种方法:原始字符串;原始字符串(即r’…’):字符串中所有字符都直接按照字面意思来使用,不转义特殊字符。
下面是使用原始字符串的代码:

print r’Hello\World\nPython’
结果为:
“Hello\World\nPython”
可以清楚看到,在使用原始字符串之后,“\n”未被转义为换行符,而是直接被输出了。

三、正则转义

好了,上面讲的只是“字符串转义”。同理,在正则表达式中也存在转义,我们姑且先称其为“正则转义”,其与“字符串转义”完全不同,比如“\d”代表数字,“\s”代表空白符。下面我们先编写开头的例子,然后再分析。
提取“3\8”反斜杠之前的数字:

import re

string = ‘3\8’
m = re.search(’(\d+)\\’, string)

if m is not None:
print m.group(1) # 结果为:3

n = re.search(r’(\d+)\’, string)

if n is not None:
print n.group(1) # 结果为:3

正则表达式字符串需要经过两次转义,这两次分别是上面的“字符串转义”和“正则转义”,个人认为“字符串转义”一定先于“正则转义”。

1)’\\'的过程:
先进行“字符串转义”,前两个反斜杠和后两个反斜杠分别被转义成了一个反斜杠;即“\|\”被转成了“|\”(“|”为方便看清,请自动忽略)。“字符串转义”后马上进行“正则转义”,“\”被转义为了“\”,表示该正则式需要匹配一个反斜杠。在“字符串转义”中,只有特殊字符,如“\n”, 中的“\”需要用“\”来进行特殊转义,其他“\”不需要特殊转义,像此例中的\d是不需要先进行字符串转义的。

2)r’\'的过程:
由于原始字符串中所有字符直接按照字面意思来使用,不转义特殊字符,故不做“字符串转义”,直接进入第二步“正则转义”,在正则转义中“\”被转义为了“\”,表示该正则式需要匹配一个反斜杠。

四、结论

也就是说原始字符串(即r’…’)与“正则转义”毫无关系,原始字符串仅在“字符串转义”中起作用,使字符串免去一次转义。
被搜索的字符串只考虑其可能的字符串转义,如果被搜索字符串中有以下特殊字符:
Python正则表达式匹配反斜杠_第1张图片
而你又要匹配其中的“\”,一定要在字符串前面加r,即使用原始字符串。如果\与相邻的字符不构成特殊字符如“\c”,不使用原始字符串,也可以成功匹配\。只要不是需要匹配上表中的特殊字符,最好使用原始字符串,这样能避免不必要的错误。
string = ‘2\c’
m = re.search(r’(\d+)\’, string)
if m is not None:
print(m.group(1))
else:
print(“none”)
output:2

string = ‘2\a’
m = re.search(r’(\d+)\’, string)
if m is not None:
print(m.group(1))
else:
print(“none”)
output:none

string = r’2\a’
m = re.search(r’(\d+)\’, string)
if m is not None:
print(m.group(1))
else:
print(“none”)
output:2

你可能感兴趣的:(Python)