【问题标题】:python3 replacing double backslash with single backslash [duplicate]python3用单反斜杠替换双反斜杠[重复]
【发布时间】:2018-10-16 09:53:12
【问题描述】:

我需要在 python3 中用复杂字符串中的\ 替换\\。我知道这个问题已经被问过好几次了,但大部分时间都是针对简单字符串的,所以(接受的)答案都不适用于复杂的字符串。

这也与this one不同,问题可以通过.decode('unicode_escape') 解决,但不适用于此问题。 见下文

假设字符串是:

my_str = '\\xa5\\xc0\\xe6aK\\xf9\\x80\\xb1\\xc8*\x01\x12$\\xfbp\x1e(4\\xd6{;Z\\x'

直截了当的方法是:

my_str.replace('\\','\')

导致:

SyntaxError:扫描字符串文字时 EOL


answer 建议使用:

my_str.replace('\\\\','\\')

结果:

'\\xa5\\xc0\\xe6aK\\xf9\\x80\\xb1\\xc8*\x01\x12$\\xfbp\x1e(4\\xd6{;Z\\x'

所以,没有变化。


这个answer 建议:

b = bytes(my_str, encoding='utf-8')
b.decode('unicode-escape')

但这不适用于如此复杂的字符串:

UnicodeDecodeError: 'unicodeescape' 编解码器无法解码位置 49-50 中的字节:截断 \xXX 转义


使用解码(建议here)会导致:

my_str.decode('unicode_escape')

AttributeError: 'my_str' 对象没有属性 'decode'


使用unicode_esacpe 编码和解码的组合返回一个完全不同的字符串(可能是由于使用utf-16,但utf-8 会导致错误,见上文。另外,例如latin1 不起作用):

my_str.encode('utf-16').decode('unicode_escape')
'ÿþ\\\x00x\x00a\x005\x00\\\x00x\x00c\x000\x00\\\x00x\x00e\x006\x00a\x00K\x00\\\x00x\x00f\x009\x00\\\x00x\x008\x000\x00\\\x00x\x00b\x001\x00\\\x00x\x00c\x008\x00*\x00\x01\x00\x12\x00$\x00\\\x00x\x00f\x00b\x00p\x00\x1e\x00(\x004\x00\\\x00x\x00d\x006\x00{\x00;\x00Z\x00\\\x00x\x00'

【问题讨论】:

  • your_text.replace('\\', '') 有效吗?你实际上没有任何双文字反斜杠......
  • 对,这行得通。一旦我将 '\' 作为第二个参数,它就不再起作用了。
  • 我猜你真的不需要这样做。通常,人们打印出值并看到双反斜杠,但这只是 Python 明确向您展示字符串中有一个反斜杠的方式。你能多说一下这个字符串的来源,以及你为什么要改变它吗?
  • @black 给我们更多细节,我们可以帮助解决问题。或者加入我们在 Freenode 上的#python IRC 频道,在这里我们可以进行实际讨论并深入了解它。

标签: python string python-3.x replace


【解决方案1】:

仔细看字符串,它们都是单斜杠。

In [26]: my_str[0]
Out[26]: '\\'

In [27]: my_str[1]
Out[27]: 'x'

In [28]: len(my_str[0])
Out[28]: 1

my_str.replace('\\','\') 将不起作用,因为这里的令牌是\',它转义' 并等待另一个关闭'
请改用my_str.replace('\\', '')


更新:几天后,我意识到以下讨论也可能会有所帮助。如果带有转义的字符串('\\x''\\u')的内涵最终是 hex/unicode 文字,则它们可以被 escape_decode 解码。

import codecs
print(len(b'\x32'), b'\x32')                # 1 hex literal, '\x32' == '2'
print(len(b'\\x32'), b'\\x32')              # 4 chars including escapes
print(codecs.escape_decode('\\x32', 'hex')) # chars->literal, 4->1

# 1 b'2'
# 4 b'\\x32'
# (b'2', 4)

s = '\\xa5\\xc0\\xe6aK\\xf9\\x80\\xb1\\xc8*\x01\x12$\\xfbp\x1e(4\\xd6{;Z'
ed, _ = codecs.escape_decode(s, 'hex')
print(len(s), s)
print(len(ed), ed)

# 49 \xa5\xc0\xe6aK\xf9\x80\xb1\xc8*$\xfbp(4\xd6{;Z
# 22 b'\xa5\xc0\xe6aK\xf9\x80\xb1\xc8*\x01\x12$\xfbp\x1e(4\xd6{;Z'

【讨论】:

    【解决方案2】:

    如果你这样做了

    s  = '\\xa5\\xc0\\xe6aK\\xf9\\x80\\xb1\\xc8*\x01\x12$\\xfbp\x1e(4\\xd6{;Z\\x'
    
    s = s.replace('\\','\')
    
    print(s)
    

    你得到了

     File "main.py", line 3
        s = s.replace('\\','\')
                             ^
    SyntaxError: EOL while scanning string literal
    

    因为在 '\' 中 \ 转义了 ' 。您的字符串处于打开状态。

    s 中没有任何双 \ - 它只是 显示 它,如果您检查它,请务必将其与用于转义内容的 \ 区分开来。

    如果你print(s),你会得到\xa5\xc0\xe6aK\xf9\x80\xb1\xc8*$\xfbp(4\xd6{;Z\x

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      • 2018-06-07
      • 2013-04-15
      相关资源
      最近更新 更多