jcpython2 发表于 2022-11-15 11:41:03

split分割\报错

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']


所以如何正确替换\和为啥第二段代码\变成\\?

jackz007 发表于 2022-11-15 11:46:22

本帖最后由 jackz007 于 2022-11-15 12:31 编辑

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

阿奇_o 发表于 2022-11-15 14:39:32

本帖最后由 阿奇_o 于 2022-11-15 18:39 编辑

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

jcpython2 发表于 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']

三个晾衣架 发表于 2022-11-16 11:15:44

阿奇_o 发表于 2022-11-15 14:39


大神,为什么这里要用三个\\\才行呢

阿奇_o 发表于 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)

ccnuhua 发表于 2022-11-17 09:50:56

小白路过,学习一下

三个晾衣架 发表于 2022-11-17 12:09:41

阿奇_o 发表于 2022-11-16 20:15
具体我也不知道。。
我推测是因为对于编译器 要处理一个反斜杠是需要两个,你也看到了不匹配反斜杠时,e ...

好的,多谢大神!

三个晾衣架 发表于 2022-11-17 12:18:48

jcpython2 发表于 2022-11-15 18:30
那第二段代码为啥ee\输出变成了ee\\?

顺着上面两位大神的思路,我觉得应该是这种情况:首先用两个\没有匹配到ee\中的\,而是匹配到了ee\后面的空格,并在此空格处分割,由于split返回的是一个列表,而ee\是该列表中的一个字符串元素,需要用引号括起来,即'ee\',但\会把后面的引号转义掉,所以计算机需要再用一个反斜杠把ee\中的反斜杠转义掉,所以计算机返回的值就是'ee\\'

三个晾衣架 发表于 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**yyzz\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'))

三个晾衣架 发表于 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
页: [1]
查看完整版本: split分割\报错