鱼C论坛

 找回密码
 立即注册
查看: 3014|回复: 10

[已解决]split分割\报错

[复制链接]
发表于 2022-11-15 11:41:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
import re
tx = 'aa,bb!cc! dd/ ee\ ff gg hh'
print(re.split(';| |,|\*|\n|//|!|\\',tx))

替换\符号的时候报错


如果不去除字符串中的\ 只写 ';| |,|\*|\n|//|!'
import re
tx = 'aa,bb!cc! dd/ ee\ ff gg hh'
print(re.split(';| |,|\*|\n|//|!',tx))

输出结果又会变成ee\\这样,多出了\
['aa', 'bb', 'cc', '', 'dd/', 'ee\\', 'ff', 'gg', 'hh']


所以如何正确替换\和为啥第二段代码\变成\\?
最佳答案
2022-11-17 12:56:10
这是输出结果:
['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh', 'xx', 'yy', 'zz', 'AA']
['\\']
['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh', 'xx', 'yy', 'zz', 'AA']
['\\']
['\\']

下面这是为啥ee\打印出来是'ee\\'的解释,不知道我写的容不容易理解:
# 斜杠\元素会把该符号后面的引号转义为普通的引号,即将引号'视为元素的一部分,而不再视为字符串的结尾。因此,计算机需要再用一个\把反斜杠转义掉,避免发生上述情况,否则将产生语法错误:
print(['\\']) # 不会报错
# print(['\']) # 语法错误:SyntaxError: unterminated string literal (字符串未结束,因\后的引号被转义,导致该引号被视为字符串的一部分,而非字符串的结尾)

# 若按字符串形式打印反斜杠\,且\不位于字符串结尾的引号前,则打印出来的字符串只有1个\:
text1 = 'ee\ ff'
i = 0
for each in text1:
    print('第%d个元素的列表形式 ---> %s 和字符串形式 ---> %s' % (i, list(each), each))
    i += 1

输出结果:
第0个元素的列表形式 ---> ['e'] 和字符串形式 ---> e
第1个元素的列表形式 ---> ['e'] 和字符串形式 ---> e
第2个元素的列表形式 ---> ['\\'] 和字符串形式 ---> \
第3个元素的列表形式 ---> [' '] 和字符串形式 --->  
第4个元素的列表形式 ---> ['f'] 和字符串形式 ---> f
第5个元素的列表形式 ---> ['f'] 和字符串形式 ---> f
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-11-15 11:46:22 | 显示全部楼层
本帖最后由 jackz007 于 2022-11-15 12:31 编辑

      '\' 是转义字符,通常需要和后续的其它字符(一个或多个)一起表达另外一个不可打印字符,字符串中如果需要出现 '\' 字符本身,那就必须写成 '\\' ,这只不过是表达问题,只有这样写了,Python 才能明白你的意思,并不会因为你写成了 '\\' 就真的成了 '\\',进入计算机内部后,实际上还是 '\',之所以要这样做,一切都只不过是为了满足人机对话的要求而已。
      当然,你也可以利用原始字符串来避免转义:r'C:\Windows\System32' ,但是,原始字符串也有一个局限,那就是 '\' 字符不能用来结尾。如果必须这样结尾,那就应该这样写: r'C:\Windows\System32' + '\\'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-15 14:39:32 | 显示全部楼层
本帖最后由 阿奇_o 于 2022-11-15 18:39 编辑
t = 'aa,bb!cc; dd/ ee\ ff gg hh*xx**yy  zz\tAA'
                       
re.split('[*,;!\s\n/\\\]+', t)
                       
['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh', 'xx', 'yy', 'zz', 'AA']
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-11-15 18:30:47 | 显示全部楼层
jackz007 发表于 2022-11-15 11:46
'\' 是转义字符,通常需要和后续的其它字符(一个或多个)一起表达另外一个不可打印字符,字符串中如 ...

那第二段代码为啥ee\输出变成了ee\\?
import re
tx = 'aa,bb!cc! dd/ ee\ ff gg hh'
print(re.split(';| |,|\*|\n|//|!',tx))
['aa', 'bb', 'cc', '', 'dd/', 'ee\\', 'ff', 'gg', 'hh']
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-16 11:15:44 | 显示全部楼层

大神,为什么这里要用三个\\\才行呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-16 20:15:27 | 显示全部楼层
三个晾衣架 发表于 2022-11-16 11:15
大神,为什么这里要用三个\\\才行呢

具体我也不知道。。
我推测是因为对于编译器 要处理一个反斜杠是需要两个,你也看到了不匹配反斜杠时,ee\ 变成了 ee\\   
所以,
如果用 r-string 语法时,就是写两个(要匹配的是两个): re.split(r'[*,;!\s\n/\\]+', t)
如果是用escape语法,就 是写三个,即:  re.split('[*,;!\s\n/\\\]+', t)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-17 09:50:56 | 显示全部楼层
小白路过,学习一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-17 12:09:41 From FishC Mobile | 显示全部楼层
阿奇_o 发表于 2022-11-16 20:15
具体我也不知道。。
我推测是因为对于编译器 要处理一个反斜杠是需要两个,你也看到了不匹配反斜杠时,e ...

好的,多谢大神!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-17 12:18:48 From FishC Mobile | 显示全部楼层
jcpython2 发表于 2022-11-15 18:30
那第二段代码为啥ee\输出变成了ee\\?

顺着上面两位大神的思路,我觉得应该是这种情况:首先用两个\没有匹配到ee\中的\,而是匹配到了ee\后面的空格,并在此空格处分割,由于split返回的是一个列表,而ee\是该列表中的一个字符串元素,需要用引号括起来,即'ee\',但\会把后面的引号转义掉,所以计算机需要再用一个反斜杠把ee\中的反斜杠转义掉,所以计算机返回的值就是'ee\\'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-17 12:49:51 | 显示全部楼层
楼主,我又试了试,最后看小甲鱼视频的时候发现,用re.findall('\\\', 'FishC.\com')会出现SyntaxError,用re.findall('\\', 'FishC.\com')会出现re.Error,然后我搜了一下这个re.Error的bad escape,正好搜到了一篇讲\的博文(https://blog.csdn.net/qq_27283619/article/details/106948855),我看了以后就明白了,感觉讲的挺清楚的,我把相应部分的解释整理了一下附在这里了:

# 正则表达式字符串中的 \ 和 Python 字符串中的 \ 转义类似,
# 他们的区别在于,正则表达式字符串的转义有 2 个水平,第 1 次是 Python 解释器层面的转义,第 2 次是 re 模块正则引擎的转义。
# 因此正则中要匹配 \ 本身,正则表达式字符串需要写成 '\\\\',如:

import re
t = 'aa,bb!cc; dd/ ee\ ff gg hh*xx**yy  zz\tAA'
t1 = re.split('[\\\\;,*\s/!]+', t)
print(t1)

print(re.findall('\\\\', 'FishC.\com'))

# 上面正则表达式字符串是 '\\\\',第 1 轮是 Python 解释器转义,转义后结果是 \\;
# 再经过 re 正则引擎的转义,转移后结果是 \,所以正则表达式字符串 '\\\\' 最终匹配的是 \ 本身。

#是不是觉得这样非常麻烦,而且容易出错,因为有 2 次转义。因此,在写正则表达式字符串时,使用原生字符串是非常推荐的写法!
# 因为这样可以减少 Python 解释器转义这一步,只需要 re 模块正则引擎转义,即可。比如,我们想匹配 \ 本身,那么我们用原生正则表达式字符串就可以写成 r'\\',如:
t2 = re.split(r'[\\;,*\s/!]+', t)
print(t2)

print(re.findall(r'\\', 'FishC.\com'))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-17 12:56:10 | 显示全部楼层    本楼为最佳答案   
这是输出结果:
['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh', 'xx', 'yy', 'zz', 'AA']
['\\']
['aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh', 'xx', 'yy', 'zz', 'AA']
['\\']
['\\']

下面这是为啥ee\打印出来是'ee\\'的解释,不知道我写的容不容易理解:
# 斜杠\元素会把该符号后面的引号转义为普通的引号,即将引号'视为元素的一部分,而不再视为字符串的结尾。因此,计算机需要再用一个\把反斜杠转义掉,避免发生上述情况,否则将产生语法错误:
print(['\\']) # 不会报错
# print(['\']) # 语法错误:SyntaxError: unterminated string literal (字符串未结束,因\后的引号被转义,导致该引号被视为字符串的一部分,而非字符串的结尾)

# 若按字符串形式打印反斜杠\,且\不位于字符串结尾的引号前,则打印出来的字符串只有1个\:
text1 = 'ee\ ff'
i = 0
for each in text1:
    print('第%d个元素的列表形式 ---> %s 和字符串形式 ---> %s' % (i, list(each), each))
    i += 1

输出结果:
第0个元素的列表形式 ---> ['e'] 和字符串形式 ---> e
第1个元素的列表形式 ---> ['e'] 和字符串形式 ---> e
第2个元素的列表形式 ---> ['\\'] 和字符串形式 ---> \
第3个元素的列表形式 ---> [' '] 和字符串形式 --->  
第4个元素的列表形式 ---> ['f'] 和字符串形式 ---> f
第5个元素的列表形式 ---> ['f'] 和字符串形式 ---> f
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-25 15:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表