如何取消转义的反斜杠字符串?


100

假设我有一个字符串,它是另一个字符串的反斜杠转义版本。在Python中,有没有一种简便的方法可以使字符串不转义?例如,我可以这样做:

>>> escaped_str = '"Hello,\\nworld!"'
>>> raw_str = eval(escaped_str)
>>> print raw_str
Hello,
world!
>>> 

但是,这涉及将(可能不受信任的)字符串传递给eval(),这是安全隐患。标准库中是否有一个函数可以接收一个字符串并生成一个不涉及安全性的字符串?

Answers:


137
>>> print '"Hello,\\nworld!"'.decode('string_escape')
"Hello,
world!"

9
是否有与python 3兼容的东西?
thejinx0r 2015年

3

29
基本上是您想要的Python3print(b"Hello,\nworld!".decode('unicode_escape'))
ChristopheD

3
对于python 3,请使用value.encode('utf-8').decode('unicode_escape')
Casey Kuball,

8
警告: value.encode('utf-8').decode('unicode_escape') 损坏字符串中的非ASCII字符。除非保证输入中仅包含ASCII字符,否则这不是有效的解决方案。
亚历克斯·彼得斯

35

您可以使用ast.literal_eval哪个是安全的:

安全地评估表达式节点或包含Python表达式的字符串。提供的字符串或节点只能由以下Python文字结构组成:字符串,数字,元组,列表,字典,布尔值和无。(结束)

像这样:

>>> import ast
>>> escaped_str = '"Hello,\\nworld!"'
>>> print ast.literal_eval(escaped_str)
Hello,
world!

3
字符串中包含转义的分号会破坏此代码。引发语法错误“行继续符后出现意外字符”
darksky 2016年

3
@darksky通知,ast库需要引号(无论是"',甚至"""''')周围的escaped_str,因为它实际上是试图运行它Python代码,但提高了安全性(防止串注射)
InQβ

@ no1xsyzy:在OP中已经是这种情况;这是正确的答案,如OP 中a 或object 的a str是;该编解码器的答案是当它不是一个,但逃脱文本的一些其他形式(不引号作为字符串数据本身的一部分包围)。reprstrbytesunicode-escaperepr
ShadowRanger

与utf-8字符这将无法正常工作。使用代码包签出最后一个答案。它实际上有效。
rubmz

FWIW,我试图解析一些转义的JSON文本,并不断收到此错误,[ERROR] TypeError: string indices must be integers并且此解决方案可以解决该问题。取消转义字符串,然后解析为JSON。
网络僧

20

所有给出的答案将在通用Unicode字符串上中断。据我所知,以下代码在所有情况下都适用于Python3:

from codecs import encode, decode
sample = u'mon€y\\nröcks'
result = decode(encode(sample, 'latin-1', 'backslashreplace'), 'unicode-escape')
print(result)

如注释中所述,您还可以像下面这样使用模块中的literal_eval方法ast

import ast
sample = u'mon€y\\nröcks'
print(ast.literal_eval(F'"{sample}"'))

当您的字符串确实包含字符串文字(包括引号)时,也可以这样:

import ast
sample = u'"mon€y\\nröcks"'
print(ast.literal_eval(sample))

但是,如果不确定输入字符串是使用双引号还是单引号作为定界符,或者不确定根本不能正确转义输入字符串,则literal_eval可能会花点时间SyntaxError编码/解码方法仍然有效。


ast.literal_eval('"mon€y\\nröcks"') == "mon€y\nröcks"使用Python 3.7.3对我来说工作正常
oldrinb

感谢您的评论@oldrinb!我编辑了答案以包括该答案。
JeskoHüttenhain

14

在python 3中,str对象没有decode方法,您必须使用bytes对象。ChristopheD的答案涵盖了python 2。

# create a `bytes` object from a `str`
my_str = "Hello,\\nworld"
# (pick an encoding suitable for your str, e.g. 'latin1')
my_bytes = my_str.encode("utf-8")

# or directly
my_bytes = b"Hello,\\nworld"

print(my_bytes.decode("unicode_escape"))
# "Hello,
# world"

2
放在一起,value.encode('utf-8').decode('unicode_escape')
Casey Kuball

6
如果字符串包含一些utf-8非ascii字符(即波兰语字符)
令人难以置信-Pax0r

您是否尝试过在致电中选择适合波兰语的编码encode
asac

与utf-8字符这将无法正常工作。使用代码包签出最后一个答案。它实际上有效。
rubmz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.