python3 reemplaza la doble barra invertida con una sola barra invertida

Necesito reemplazar \\ con \ en python3 en una cadena compleja. Sé que esta pregunta se ha formulado varias veces, pero la mayor parte del tiempo para cadenas simples, de modo que ninguna de las respuestas (aceptadas) realmente funciona para cadenas complejas.

Esto también es diferente de este, donde el problema podría resolverse con .decode('unicode_escape') que no funciona para este problema. Ver abajo .

Suponiendo que la cadena es:

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

El enfoque directo sería:

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

lo que lleva a:

SyntaxError: EOL al escanear la cadena literal


Esta respuesta sugiere usar:

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

Lo que resulta en:

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

Entonces, no hay cambio.


Esta respuesta sugiere:

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

Pero esto no funciona para una cadena tan compleja:

UnicodeDecodeError: el codec ‘unicodeescape’ no puede decodificar bytes en la posición 49-50: truncado \ xXX escape


Usar deencoding (como se sugiere aquí ) da como resultado:

 my_str.decode('unicode_escape') 

AttributeError: el objeto ‘my_str’ no tiene atributo ‘decodificar’


Una combinación de encoding y luego deencoding usando unicode_esacpe devuelve una cadena totalmente diferente (probablemente debido al uso de utf-16 , pero utf-8 produce un error, ver más arriba. Además, por ejemplo, latin1 no funciona):

 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' 

Eche un vistazo más de cerca a la cadena, todos ellos son una sola barra.

 In [26]: my_str[0] Out[26]: '\\' In [27]: my_str[1] Out[27]: 'x' In [28]: len(my_str[0]) Out[28]: 1 

Y my_str.replace('\\','\') no funcionará porque el token aquí es \' , que se escapa ' y espera el otro cierre ' .
Utilice my_str.replace('\\', '') lugar


Actualización: después de unos días más, me doy cuenta de que la siguiente discusión también puede ser útil. Si la intención de una cadena con escape ( '\\x' o '\\u' ) son eventualmente literales hex / unicode, se pueden decodificar con 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' 

Si lo haces

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

usted obtiene

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

porque en '\' el \ escapa del ' . Su cadena se deja abierta.

No tiene doble \ en s – es solo mostrarlo como tal, sí lo distingue de \ usado para escapar de las cosas si lo inspecciona.

Si print(s) obtiene \xa5\xc0\xe6aK\xf9\x80\xb1\xc8*$\xfbp(4\xd6{;Z\x