-1

(Python 3.3.2) 我必须取消对 re.escape() 调用返回的一些非 ASCII 转义字符的转义。我在这里这里看到了不起作用的方法。我在 100% UTF-8 环境中工作。

# pure ASCII string : ok
mystring = "a\n" # expected unescaped string : "a\n"
cod = codecs.getencoder('unicode_escape')
print( cod(mystring) )

# non ASCII string : method #1
mystring = "€\n"
# equivalent to : mystring = codecs.unicode_escape_decode(mystring)
cod = codecs.getdecoder('unicode_escape')
print(cod(mystring))
# RESULT = ('â\x82¬\n', 5) INSTEAD OF ("€\n", 2)

# non ASCII string : method #2
mystring = "€\n"
mystring = bytes(mystring, 'utf-8').decode('unicode_escape')
print(mystring)
# RESULT = â\202¬ INSTEAD OF "€\n"

这是一个错误吗?我误解了什么吗?

任何帮助,将不胜感激 !

PS:感谢 Michael Foukarakis 的评论,我编辑了我的帖子。

4

3 回答 3

2

我猜你需要处理的实际字符串是mystring = €\\n

mystring = "€\n"  # that's 2 char, "€" and new line
mystring = "€\\n" # that's 3 char, "€", "\" and "n"

我真的不明白python3内部encode()和内部decode()出了什么问题,但是我的朋友在我们编写一些工具时解决了这个问题。

我们所做的就是在逃逸程序完成后绕过。encoder("utf_8")

>>> "€\\n".encode("utf_8")
b'\xe2\x82\xac\\n'
>>> "€\\n".encode("utf_8").decode("unicode_escape")
'â\x82¬\n'
>>> "€\\n".encode("utf_8").decode("unicode_escape").encode("utf_8")
b'\xc3\xa2\xc2\x82\xc2\xac\n'  # we don't want this
>>> bytes([ord(char) for char in "€\\n".encode("utf_8").decode("unicode_escape")])
b'\xe2\x82\xac\n'  # what we really need
>>> str(bytes([ord(char) for char in "€\\n".encode("utf_8").decode("unicode_escape")]), "utf_8")
'€\n'

我们可以看到:虽然结果decode("unicode_escape")看起来是连线的,但bytes对象实际上包含字符串的正确字节(使用 utf-8 编码),在这种情况下,"\xe2\x82\xac\n"

而且我们现在不str直接打印对象,我们也不使用encode("utf_8"),我们ord()用来创建bytes对象b'\xe2\x82\xac\n'

你可以str从这个bytes对象中得到正确的,把它放进去str()


顺便说一句,我和我的朋友想要制作的工具是一个包装器,它允许用户输入类似 c 的字符串文字,并自动转换转义序列。

User input:\n\x61\x62\n\x20\x21  # 20 characters, which present 6 chars semantically
output:  # \n
ab       # \x61\x62\n
 !       # \x20\x21

这是用户在终端中输入一些不可打印字符的强大工具。

我们的最终工具是:

#!/usr/bin/env python3
import sys 

for line in sys.stdin:
    sys.stdout.buffer.write(bytes([ord(char) for char in line[:-1].encode().decode('unicode_escape')]))
    sys.stdout.flush()
于 2015-12-23T15:41:08.967 回答
1

您似乎误解了编码。为了防止常见错误,我们通常在字符串离开应用程序时对其进行编码,并在它进入时对其进行解码。

首先,让我们看一下 unicode_escape 的文档,其中指出:

产生 [s] 一个适合作为 Python 源代码中的 Unicode 文字的字符串。

以下是您将从网络或声称其内容是 Unicode 转义的文件中获得的内容:

b'\\u20ac\\n'

现在,您必须对其进行解码才能在您的应用程序中使用它:

>>> s = b'\\u20ac\\n'.decode('unicode_escape')
>>> s
'€\n'

如果你想把它写回,比如说,一个 Python 源文件:

with open('/tmp/foo', 'wb') as fh: # binary mode
    fh.write(b'print("' + s.encode('unicode_escape') + b'")')
于 2013-08-28T14:31:53.573 回答
0
于 2013-08-28T16:30:01.527 回答