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

这里是一点小心得:由于下面两个原因,在正则表达式中使用反斜杠就会产生了一个双重转换的问题。
(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
[]

时间: 2024-10-12 10:30:34

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

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

这里是一点小心得:由于下面两个原因,在正则表达式中使用反斜杠就会产生了一个双重转换的问题.(1).python自身处理字符串时,反斜杠是用于转义字符 (2).正则表达式也使用反斜杠来转义字符     要匹配字符串中1个反斜杠应该怎么写正则表达式?"\\",这样行吗?试试就知道了,re模块抛异常了,因为在正则表达式中,"\\"就是一个反斜杠,对于正则表达式解析器来说,是一个转义字符,但是后面啥也没有,自然就报错了,"\\\"三个肯定是不行的,试试四

Python: 正则表达式匹配反斜杠 "\"

Python正则表达式匹配反斜杠 "\" eg: >>>a='w\w\w' 'w\\w\\w' #  打印出来的 "\\" 被转义成 一个反斜杠 "\" 如果需要匹配字符串a,需要匹配一个反斜杠 "\" >>>re.split(r'\\',a) ['w','w','w',] 先对字符串转义,再进行正则表达式转义 由于原始字符串中所有字符直接按照字面意思来使用,不转义特殊字符,故不做字符串转义

python IDLE中反斜杠显示为人民币符号¥

Python自带的IDE是IDLE,最简单不过,但是全国二级要求使用该IDE. 该IDE相对于其他更高级的IDE,例如PyCharm和Visual Studio Code等,功能明确弱得很.但是,就应对二级Python考试来说已经绰绰有余. 问题 在其内置的命令行环境下现遇到一个小问题是:反斜杠显示为人民币符号¥,无论当前输入法是中文还是英文输入法.参考下图: 分析与解决办法 经过试验发现,可以通过菜单命令"Options"-"Configure IDLE",把当前

关于Python中正则表达式的反斜杠问题

之前总是搞不明白正则表达式中的反斜杠的问题.今天经过查阅资料终于搞明白了. 其中最重要的一点就是Python自己的字符串中定义的反斜杠也是转义字符,而正则表达式中的反斜杠也是转义字符,所以正则表达式中反斜杠会涉及到双重转换的问题. 要匹配字符串中1个反斜杠应该怎么写正则表达式?"\\",这样行吗?试试就知道了,re模块抛异常了,因为"\\"就是一个反斜杠,对于正则表达式解析器来说,是一个转义字符,但是后面啥也没有,自然就报错了,"\\\"三个肯定

C#中反斜杠/n与/r的区别

最近在公司实习的过程中,遇到了字符串换行的问题,百度了一下,发现字符串换行的问题还挺多,总结一下最基本的点,以防忘记. \n—>换行符(New Line),作用为换行符后面的字符串显示到“下一行开头的位置” Console.Write("功能如下:[微官网]随时随地访问方正中期,掌握最新期货信息.\n[微开户]下载方正小方开户客户端,移动开户更加方便快捷.\n[菜单]1.期货资讯 2.股票资讯 3.意见反馈"); 显示如下: \n后面的字符串会另起新行显示. \r—>回车符

AS3中正则表达式对反斜杠的替换

一个有趣的小问题,下面的正则表达式能替换成功么? var __str:String = \'12346789\'; trace(__str.replace(/\\/g, \'5\')); 答案是:不能.trace出来的结果为: [trace] 12346789 其实正则本身并没有写错,错在被替换的字符串.反斜杠“”在AS3中是转义符,会将其后的任何值转换为本身,因此看到的字符串其实本身就是12346789,也就是没有反斜杠,当然无法搜索到. 直接trace(__str),结果和上面的trace相

正则表达式匹配反斜杠——匹配一个反斜杠要用四个反斜杠

正则表达式中匹配一个反斜杠要用四个反斜杠,为什么呢? 分析一下"\\\\",第一个斜杠是转义符,第二个斜杠是斜杠本身,第三个斜杠是转义符,第四个斜杠是斜杠本身. 有2点要清楚: 1.字符串里面表示斜杠就需要两个斜杠如"\\" 2.正则表达式里的斜杠需要转意,是用"\\"标示. 这样就比较好解释: 我们先要表示正则表达式里面的斜杠"\\",然后再用字符串表示出来.而这2个斜杠分别需要一个转义符,这样就成了4个斜杠在正则表达式里面

怎么过滤JSON数组中反斜杠“\”,反序列化

原因就是json数组被序列化了两次,反序列化回来就可以. JSON数组 jsonarray 是 [object,object] 的形式; 序列化即 : JSON.stringify(jsonarry)就变成了[{"id","2"},{"name","tt"}]这种形式. 反序列化即 : JSON.parse(jsonarry)又变成了 [object,object],但是它传到后端后反斜杠就没了,这就是JSON数组反序列化的神

如何去掉Json字符串中反斜杠

在做项目中,前台传来的数据为Json字符串,因为没有合适的实体来这些字段,所有就用了最简单的方式:截取字符串. 前台Json字符串为: <span style="font-size:18px;">string s1 ="[{\"ID\":\"99d2a341-ea2e-4f04-b4f4-623153d64336\",\"Name\":\"王五\",\"TotalScores