【问题标题】:How to store backslash unescaped string in a variable?如何将反斜杠未转义的字符串存储在变量中?
【发布时间】:2019-07-25 06:31:21
【问题描述】:

很多关于非转义字符串的问题似乎与 Python 2 或非转义 unicode 字符代码有关。

我从 LDAP 返回了一个似乎是“双重转义”的字符串:

>>> escaped = "hello\\,world"

我想取消转义这个字符串并将其存储到另一个变量中,但 decode 没有返回我所期望的:

>>> escaped.encode().decode('unicode_escape')
'hello\\,world'

print() 的结果却返回了我想要的结果:

>>> print(escaped)
hello\,world

我知道我可以捕获result of that print to an IO stream,但肯定有比这更优雅的解决方案吗?

【问题讨论】:

  • "hello\\,world" 没有双重转义甚至转义。尝试按原样打印它,您将看到>>> print("hello\\,world") hello\,world。 XY 问题?你真正的问题是什么?
  • 我认为取消转义一次应该产生hello\,world,然后第二次应该产生hello,world。这不正确吗?
  • 在 REPL 中打印命令结果时会发生转义。始终使用print 测试您的结果,因为这就是将在文件中显示/存储的内容,等等...您在哪里取消转义 BTW?你想逃跑吗?
  • 我只是想存储未转义的值以供以后显示。我对未转义值 hello\,world 的理解是,它仍然被转义以明确表明逗号不应被视为 LDAP DN 字符串的一部分。
  • 您的数据实际上包含hello\,world。使用 print 为您提供显示的内容,使用 REPL 中的返回值为您提供可以在 python 中粘贴回的值,这说明有一个双“\\”

标签: python-3.x unicode escaping


【解决方案1】:

'hello\\world' 没有双重转义 - 只是在显示字符串的内部表示(又名“repr”)时,Python 确实转义反斜杠,以便查看此表示的人知道\\ 表示字符串中实际的单个反斜杠字符,而不是另一个字符的转义序列。

当您调用print 时,字符串表示是通过另一种方法完成的,该方法用于程序输出 - 即供程序用户使用。在这个表示上,“\”被正确地呈现为“\”,而其他序列,例如“\n”、“\t”、“\b”被呈现为它们所代表的真实字符(“\x0a”、在这种情况下为“\x09”和“\x07” - 或“LINE FEED”、“TAB”和“BACKSPACE”)。

前者是Python通过在任何对象中调用__repr__方法来渲染的,它是任何Python交互环境用来展示表达式结果的。 print 使用的后期渲染发生在调用对象的 __str__ 方法时。在代码中,不要直接调用这些方法,而应该分别调用内置的repr(...)str(...)

此外,通过使用 f 字符串,可以很容易地在另一个 text-sn-p 中插入所需的对象视图。如果您想要“str”视图,只需将对象作为表达式放在 f 字符串内的 {} 之间。如果需要内部表示,在结束 } 之前,包括 !r 序列:

In [192]: a = "Hello\world!"                                                                                             

In [193]: a                                                                                                              
Out[193]: 'Hello\\world!'

In [194]: print(a)                                                                                                       
Hello\world!

In [195]: print(repr(a))                                                                                                 
'Hello\\world!'

In [196]: print(f"*{a}*{a!r}*")                                                                                          
*Hello\world!*'Hello\\world!'*

如您所见,即使键入单个“\”,如果它后面的字符没有形成已知的转义序列,则“\”会单独出现 - 但显示为“\”,因为我们人类是没有义务记住哪些是有效的转义序列,哪些不是。另一方面,在文字字符串中键入一个表示反冲的“\”是非常危险的,因为很有可能会创建一个意想不到的其他字符。在 Python 3.8(目前处于测试阶段)中,这甚至会产生语法警告:

Python 3.8.0b2+ (heads/3.8:028f1d2479, Jul 17 2019, 22:42:16) 
[GCC 9.1.1 20190503 (Red Hat 9.1.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = "hello\world!"
<stdin>:1: SyntaxWarning: invalid escape sequence \w

避免此警告的方法是始终键入双精度 \\ 或使用 r' 前缀作为字符串:

>>> a = r"hello\world!"

【讨论】:

  • 我最初回到这里是想我可以删除这个问题,因为我犯了一个根本性的错误。然而,这个问题和答案可能有助于告知其他有同样误解的人,比如我自己和你的答案,特别是解释strrepr,同时还提到 f 字符串非常棒。谢谢你。有什么比一开始就不是问题而得到解决的问题更好的了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-02
  • 1970-01-01
  • 2012-01-26
  • 2021-12-16
相关资源
最近更新 更多