Python 如何将非ascii字符打印为\uxxx

Python 如何将非ascii字符打印为\uxxx,python,python-3.x,unicode,python-3.4,non-ascii-characters,Python,Python 3.x,Unicode,Python 3.4,Non Ascii Characters,我该怎么做?我想将字符串中的所有非ascii字符打印为unicode转义文字您可以使用以下命令将字符串转换为调试表示形式,将非ascii、不可打印字符转换为转义序列: 作为repr(),返回包含对象可打印表示形式的字符串,但使用\x,\u或\u转义repr()返回的字符串中的非ASCII字符 对于U+0100-U+FFFF范围内的Unicode码点,这将使用\uhhh转义;对于拉丁语-1范围(U+007F-U+00FF),使用转义符。请注意,输出符合重新创建字符串的有效Python语法,因此包含

我该怎么做?我想将字符串中的所有非ascii字符打印为unicode转义文字

您可以使用以下命令将字符串转换为调试表示形式,将非ascii、不可打印字符转换为转义序列:

作为
repr()
,返回包含对象可打印表示形式的字符串,但使用
\x
\u
\u
转义
repr()
返回的字符串中的非ASCII字符

对于U+0100-U+FFFF范围内的Unicode码点,这将使用
\uhhh
转义;对于拉丁语-1范围(U+007F-U+00FF),使用转义符。请注意,输出符合重新创建字符串的有效Python语法,因此包含引号:

# this is what I want

print('你好')

# \uXXXX \uXXXX
如果您必须拥有
\uhhh
的所有功能,您必须自己进行转换:

>>> print('你好')
你好
>>> print(ascii('你好'))
'\u4f60\u597d'
>>> print(ascii('ASCII is not changed, Latin-1 (åéîøü) is, as are all higher codepoints, such as 你好'))
'ASCII is not changed, Latin-1 (\xe5\xe9\xee\xf8\xfc) is, as are all higher codepoints, such as \u4f60\u597d'

请注意,如果不将
\
替换为
\\
,您想要的东西是不可逆的;您无法知道实际字符串是否为
好'(一个字符)或
'\\u597d'
(ascii范围内的6个字符),因为这两个字符都会产生
\u597d
作为输出。Martijn的建议使用反斜杠替换,并且是可逆的

您可以自己进行转换:

>>> print(escape_unicode('你好'))
\u4f60\u597d
>>> print(escape_unicode('ASCII is not changed, Latin-1 (åéîøü) is, as are all higher codepoints, such as 你好'))
ASCII is not changed, Latin-1 (\u00e5\u00e9\u00ee\u00f8\u00fc) is, as are all higher codepoints, such as \u4f60\u597d

这将创建一个自定义编码错误处理程序,该处理程序通过用unicode转义替换有问题的字符来处理unicode编码错误。你可以像
一样使用它你好'.encode('ascii','UnicodeScapeSeplace')
,或者像上面的例子一样,将标准输出替换为自动将其用于所有编码的标准输出。

按照Martijn Pieters的解释,通过使用
ascii
内置输入获得正常表示

如果您确实想持续打印\u转义,可以手动执行:

注意:我确实知道eval是邪恶的,但在那个特定的用例中,我知道内部字符串不包含
,并且它被封装在
中,因此它不能仅仅是编码字符的转换-但我决不会在外部字符串上这样做,除非至少测试
t.contains(“”)


NB2:此方法无法正确处理代码大于0xffff的字符-如果不是这样,则需要另一个字符…

Python 3中的字符串默认应使用utf-8。正确的修复方法是找出为什么字符串是ASCII而不是utf-8,并修复它。@Alan是的,我不知道。我将删除无用的注释:D,但您是否仍能以这种方式使用异常处理并简单地用其他语句替换哑打印语句?(前提是您不想像Ru毯Smoker建议的那样修复编码错误)@Ru毯Smoker字符串在Python 3中默认情况下不是UTF-8,默认情况下是Unicode,并将其打印编码为
sys.stdout.encoding
,它可能是UTF-8,也可能不是UTF-8。出于标准化的原因,是否可以将所有内容强制到
\uxxx
?@Alan:不使用
ascii()
函数。那你就得手动操作了。还请注意,对于BMP以外的任何内容(U+FFFF上的代码点),您必须使用Python中的
\uhhhhhhh
表示法。你想解决什么问题?
import re

def escape_unicode(t, _p=re.compile(r'[\u0080-\U0010ffff]')):
    def escape(match):
        char = ord(match.group())
        return '\\u{:04x}'.format(char) if char < 0x10000 else '\\U{:08x}'.format(char)
    return _p.sub(escape, t)
>>> print(escape_unicode('你好'))
\u4f60\u597d
>>> print(escape_unicode('ASCII is not changed, Latin-1 (åéîøü) is, as are all higher codepoints, such as 你好'))
ASCII is not changed, Latin-1 (\u00e5\u00e9\u00ee\u00f8\u00fc) is, as are all higher codepoints, such as \u4f60\u597d
def unicodeescape(s):
    return ''.join(c if ord(c) < 128 else '\\u%04x' % ord(c) for c in s)

print(unicodeescape('你好'))
import codecs, sys

def unicodeescapereplace(error):
    if isinstance(error, UnicodeEncodeError):
        s = error.object[error.start:error.end]
        repl = ''.join('\\u%04x' % ord(c) for c in s)
        return (repl, error.end)
    raise error

codecs.register_error('unicodeescapereplace', unicodeescapereplace)
sys.stdout = codecs.getwriter('ascii')(sys.stdout.buffer, 'unicodeescapereplace')

print('你好')
t = 'ASCII is not changed, Latin-1 (åéîøü) is, as are all higher codepoints, such as 你好'
disp = u = "'" + ''.join([c if (ord(c) < 128) else r'\u%04x' % (ord(c),) for c in t ]) + "'"
print(disp)
print(eval(disp))