码迷,mamicode.com
首页 > 编程语言 > 详细

python 正则表达式中反斜杠(\)的麻烦和陷阱

时间:2014-11-28 22:34:26      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:style   color   使用   sp   for   strong   文件   on   div   

这里是一点小心得:由于下面两个原因,在正则表达式中使用反斜杠就会产生了一个双重转换的问题。
(1)、python自身处理字符串时,反斜杠是用于转义字符

(2)、正则表达式也使用反斜杠来转义字符

 

    要匹配字符串中1个反斜杠应该怎么写正则表达式?"\\",这样行吗?试试就知道了,re模块抛异常了,因为在正则表达式中,"\\"就是一个反斜杠,对于正则表达式解析器来说,是一个转义字符,但是后面啥也没有,自然就报错了,"\\\"三个肯定是不行的,试试四个"\\\\",完美匹配。

 
代码如下:
import re
re_str_patt = "\\\\"
reObj = re.compile(re_str_patt)
str_test = "abc\\cd\\hh"
print reObj.findall(str_test)

输出[‘\\‘, ‘\\‘]
备注:
     1、第二行代码只使用了python非原生字符串,所以它在正则表达式中表示的是一个反斜杠。(即四合一)
     2、由于python字符串中,反斜杠表示转义,所以第四行代码中的字符串表示的是:
        abc后是一个反斜杠,然后接cd,再接一个反斜杠,然后是hh
     3、代码段输出的是一个列表,列表中有两个元素。每一个元素都是一个字符串(python中的字符串),
        所以列表的第一个元素实际是表示一个反斜杠,同样,列表的第二个元素也是表示一个反斜杠。
     4、输出也可能是这样的:[r‘\‘, r‘\‘] 两种输种输出效果是一致的。
 
 
代码如下改动:
 
import re
re_str_patt = r"\\\\"
reObj = re.compile(re_str_patt)
str_test = "abc\\cd\\hh"
print reObj.findall(str_test)


输出:[]
备注: 1、第二行代码改成了原生字符串,此时正则表达式要匹配的则是两个连续的反斜杠。(即二合一
       2、第四行代码中的字符串表示的是:abc后是一个反斜杠,然后接cd,再接一个反斜杠,然后是hh。
       3、所以没有匹配的内容,输出为一个空列表。
 

     对于第一段代码要这么理解,首先第一重转换是字符串自身的转义,那么"\\\\",实际上就是表示两个反斜杠(两个字符),然后传入正则表达式解析器,因为反斜杠依然是转义字符,那么进行第二重转换,两个反斜杠就代表一个反斜杠,所以就能和一个反斜杠进行匹配了,那么匹配连续的两个反斜杠,写正则表达式时就要写8次"\"了,相当壮观。\d+在正则表达式里面表示匹配连续1一个以上的数字字符,可是如果想匹配:一个反斜杠,后接字母d,再接一个加号 ,这个字符串怎么写呢?(答案:"\\\\d\\+")
代码如下:

import re
re_str_patt = "\\\\d\\+"
print re_str_patt
reObj = re.compile(re_str_patt)
print reObj.findall("\\d+")
 
输出:\\d\+
      [‘\\d+‘]

 
     写成re_str_patt = "\\\\d\+"也行,因为\+对于字符串来说,没有转义意义,所以就当成一个反斜杠了。
在python中写正则表达式时用得最多的是raw字符串,原生字符串,什么意思?就是只有一重转换了,没有字符串转换了,只在正则表达式内部进行转换了,这样匹配一个反斜杠的正则表达式可以这样写,re_str_patt = r"\\"。
 
     有人会想,以后写windows的文件路径什么的方便了,呵呵直接 path = r"c:\myforder\xx" 搞定,是的,这句没有问题,但是如果你写成 path = r"c:\myforder\xx\",直接报错了,为什么?因为反斜杠虽然不作为转义字符了,但是还是对它后面的引号(包括单引号)有影响,使这个引号不被视为字符串的终止,以为它后面还有字符,但是实际没有,因此会报错。
 
    其实可以反过来想raw字符串里面要表示引号怎么办呢?,可以发现 path = r"\\123\"xxx" 是可以的,那用raw字符串岂不是有局限性?不过raw在设计之初就是用来支持正则表达式的,而在正则里面反斜杠是转义字符,所以不可能出现在字符串的末尾的,所以建议不要图方便在其他的地方使用raw。
 

实例验证之一: 

 

>>> import re
>>> s = ‘123\nabc‘    #表示的是:123 接一个换行符再接abc
>>> m = r‘123\nabc‘   #表示的是:123一个反斜杠后接n再接abc
>>> len(s)
7
>>> len(m)
8
>>>
>>> re.subn(‘\n‘,‘x‘,s)      #正则表达式匹配的是:一个换行符          

                         #要匹配的字符串s为:123 一个换行符再接abc
(‘123xabc‘, 1)
>>> re.subn(‘\\n‘,‘x‘,s)     #正则表达式匹配的是:一个换行符

                         #要匹配的字符串s为:123 一个换行符再接abc

(‘123xabc‘, 1)
>>> re.subn(‘\\\n‘,‘x‘,s)    #正则表达式匹配的是:一个换行符(有待推敲)

                         #要匹配的字符串s为:123 一个换行符再接abc
(‘123xabc‘, 1)
>>> re.subn(‘\\\\n‘,‘x‘,s)   #正则表达式匹配的是:一个反斜杠n

                         #要匹配的字符串s为:123 一个换行符再接abc
(‘123\nabc‘, 0)
>>> re.subn(‘\n‘,‘x‘,m)      #正则表达式匹配的是:一个换行符

                         #要匹配的字符串m为:123一个反斜杠后接n再接abc
(‘123\\nabc‘, 0)
>>> re.subn(‘\\n‘,‘x‘,m)     #正则表达式匹配的是:一个换行符

                         #要匹配的字符串m为:123一个反斜杠后接n再接abc
(‘123\\nabc‘, 0)
>>> re.subn(‘\\\n‘,‘x‘,m)    #正则表达式匹配的是:一个换行符(有待推敲)

                         #要匹配的字符串m为:123一个反斜杠后接n再接abc
(‘123\\nabc‘, 0)
>>> re.subn(‘\\\\n‘,‘x‘,m)   #正则表达式匹配的是:一个反斜杠n

                         #要匹配的字符串m为:123一个反斜杠后接n再接abc
(‘123xabc‘, 1)
>>>
>>>
>>> re.subn(r‘\n‘,‘x‘,s)      #正则表达式匹配的是:一个换行符

                          #要匹配的字符串s为:123 一个换行符再接abc
(‘123xabc‘, 1)
>>> re.subn(r‘\\n‘,‘x‘,s)     #正则表达式匹配的是:一个反斜杠n

                          #要匹配的字符串s为:123 一个换行符再接abc
(‘123\nabc‘, 0)
>>> re.subn(r‘\\\n‘,‘x‘,s)    #正则表达式匹配的是:一个反斜杠一个换行符

                          #要匹配的字符串s为:123 一个换行符再接abc
(‘123\nabc‘, 0)
>>> re.subn(r‘\\\\n‘,‘x‘,s)   #正则表达式匹配的是:两个反斜杠n

                          #要匹配的字符串s为:123 一个换行符再接abc
(‘123\nabc‘, 0)
>>> re.subn(r‘\n‘,‘x‘,m)      #正则表达式匹配的是:一个换行符

                          #要匹配的字符串m为:123一个反斜杠后接n再接abc
(‘123\\nabc‘, 0)
>>> re.subn(r‘\\n‘,‘x‘,m)     #正则表达式匹配的是:一个反斜杠n

                          #要匹配的字符串m为:123一个反斜杠后接n再接abc
(‘123xabc‘, 1)
>>> re.subn(r‘\\\n‘,‘x‘,m)    #正则表达式匹配的是:一个反斜杠一个换行符

                          #要匹配的字符串m为:123一个反斜杠后接n再接abc
(‘123\\nabc‘, 0)
>>> re.subn(r‘\\\\n‘,‘x‘,m)   #正则表达式匹配的是:两个反斜杠n

                          #要匹配的字符串m为:123一个反斜杠后接n再接abc
(‘123\\nabc‘, 0)

 

 

实例验证之二:

 

>>> import re
>>> s = ‘123\nabc‘
>>> m = r‘123\nabc‘
>>> len(s)
7
>>> len(m)
8
>>>
>>> re.findall(‘\n‘,s)      #正则表达式匹配的是:一个换行符          

                         #要匹配的字符串s为:123 一个换行符再接abc
[‘\n‘]
>>> re.findall(‘\\n‘,s)     #正则表达式匹配的是:一个换行符

                         #要匹配的字符串s为:123 一个换行符再接abc

[‘\n‘]
>>> re.findall(‘\\\n‘,s)    #正则表达式匹配的是:一个换行符(有待推敲)

                         #要匹配的字符串s为:123 一个换行符再接abc
[‘\n‘]
>>> re.findall(‘\\\\n‘,s)   #正则表达式匹配的是:一个反斜杠n

                         #要匹配的字符串s为:123 一个换行符再接abc
[]
>>> re.findall(‘\n‘,m)      #正则表达式匹配的是:一个换行符

                         #要匹配的字符串m为:123一个反斜杠后接n再接abc
[]
>>> re.findall(‘\\n‘,m)     #正则表达式匹配的是:一个换行符

                         #要匹配的字符串m为:123一个反斜杠后接n再接abc
[]
>>> re.findall(‘\\\n‘,m)    #正则表达式匹配的是:一个换行符(有待推敲)

                         #要匹配的字符串m为:123一个反斜杠后接n再接abc
[]
>>> re.findall(‘\\\\n‘,m)   #正则表达式匹配的是:一个反斜杠n

                         #要匹配的字符串m为:123一个反斜杠后接n再接abc
[‘\\n‘]
>>>
>>>
>>> re.findall(r‘\n‘,s)
      #正则表达式匹配的是:一个换行符

                          #要匹配的字符串s为:123 一个换行符再接abc
[‘\n‘]
>>> re.findall(r‘\\n‘,s)
      #正则表达式匹配的是:一个反斜杠n

                          #要匹配的字符串s为:123 一个换行符再接abc
[]
>>> re.findall(r‘\\\n‘,s)
    #正则表达式匹配的是:一个反斜杠一个换行符

                          #要匹配的字符串s为:123 一个换行符再接abc
[]
>>> re.findall(r‘\\\\n‘,s)
    #正则表达式匹配的是:两个反斜杠n

                          #要匹配的字符串s为:123 一个换行符再接abc
[]
>>> re.findall(r‘\n‘,m)
      #正则表达式匹配的是:一个换行符

                          #要匹配的字符串m为:123一个反斜杠后接n再接abc
[]
>>> re.findall(r‘\\n‘,m)
    #正则表达式匹配的是:一个反斜杠n

                          #要匹配的字符串m为:123一个反斜杠后接n再接abc
[‘\\n‘]
>>> re.findall(r‘\\\n‘,m)
   #正则表达式匹配的是:一个换行符(有待推敲)

                         #要匹配的字符串m为:123一个反斜杠后接n再接abc
[]
>>> re.findall(r‘\\\\n‘,m)
   #正则表达式匹配的是:两个反斜杠n

                          #要匹配的字符串m为:123一个反斜杠后接n再接abc
[]

python 正则表达式中反斜杠(\)的麻烦和陷阱

标签:style   color   使用   sp   for   strong   文件   on   div   

原文地址:http://www.cnblogs.com/fclbky/p/4129394.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!