如何取消转义反斜杠转义的字符串?[重复]
- 2025-01-14 08:50:00
- admin 原创
- 99
问题描述:
假设我有一个字符串,它是另一个字符串的反斜杠转义版本。在 Python 中,有没有一种简单的方法来取消转义该字符串?例如,我可以这样做:
>>> escaped_str = '"Hello,\\nworld!"'
>>> raw_str = eval(escaped_str)
>>> print raw_str
Hello,
world!
>>>
但是这需要将(可能不受信任的)字符串传递给 eval(),这存在安全风险。标准库中是否有一个函数可以接受字符串并生成一个没有安全隐患的字符串?
解决方案 1:
>>> print '"Hello,\\nworld!"'.decode('string_escape')
"Hello,
world!"
解决方案 2:
您可以使用ast.literal_eval
安全的:
安全地评估表达式节点或包含 Python 表达式的字符串。提供的字符串或节点只能由以下 Python 文字结构组成:字符串、数字、元组、列表、字典、布尔值和 None。(END)
像这样:
>>> import ast
>>> escaped_str = '"Hello,\\nworld!"'
>>> print ast.literal_eval(escaped_str)
Hello,
world!
解决方案 3:
所有给出的答案都会在通用 Unicode 字符串上中断。据我所知,以下内容在所有情况下都适用于 Python3:
from codecs import encode, decode
sample = u'mon€y\\nröcks'
result = decode(encode(sample, 'latin-1', 'backslashreplace'), 'unicode-escape')
print(result)
在最近的 Python 版本中,无需导入也可以运行此操作:
sample = u'mon€y\\nröcks'
result = sample.encode('latin-1', 'backslashreplace').decode('unicode-escape')
正如obataku所建议的,您也可以使用模块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
问题,但编码/解码方法仍然有效。
解决方案 4:
对于 Python3,请考虑:
my_string.encode('raw_unicode_escape').decode('unicode_escape')
“raw_unicode_escape”编解码器编码为 latin1,但首先用转义'/uXXXX'
或'UXXXXXXXX'
形式替换所有其他 Unicode 代码点。重要的是,它与普通的“unicode_escape”编解码器不同,因为它不会触及现有的反斜杠。
因此,当应用正常的“unicode_escape”解码器时,新转义的代码点和最初转义的元素都会被平等对待,结果是未转义的本机 Unicode 字符串。
(“raw_unicode_escape”解码器似乎只关注'/uXXXX'
和'UXXXXXXXX'
形式,而忽略所有其他转义。)
文档:
https://docs.python.org/3/library/codecs.html? highlight=codecs#text-encodings
解决方案 5:
在 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"
解决方案 6:
自定义字符串解析器只解码一些反斜杠转义符,在本例中"
是'
def backslash_decode(src):
"decode backslash-escapes"
slashes = 0 # count backslashes
dst = ""
for loc in range(0, len(src)):
char = src[loc]
if char == "\\\":
slashes += 1
if slashes == 2:
dst += char # decode backslash
slashes = 0
elif slashes == 0:
dst += char # normal char
else: # slashes == 1
if char == '"':
dst += char # decode double-quote
elif char == "'":
dst += char # decode single-quote
else:
dst += "\\\" + char # keep backslash-escapes like
or
slashes = 0
return dst
src = "a" + "\\\\\" + r"\'" + r'\"' + r"
" + r" " + r"x" + "z" # input
exp = "a" + "\\\" + "'" + '"' + r"
" + r" " + r"x" + "z" # expected output
res = backslash_decode(src)
print(res)
assert res == exp