繁体   English   中英

如何将非ASCII字符打印为\\ uXXXX

[英]How to print non-ascii characters as \uXXXX

# what I currently have

print('你好')

# 你好

# this is what I want

print('你好')

# \uXXXX \uXXXX

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

您可以使用ascii()函数将字符串转换为带有非ASCII,非可打印字符的调试表示形式,这些字符会转换为转义序列:

作为repr() ,返回一个包含对象可打印表示形式的字符串,但是使用\\x\\u\u003c/code>或\\U转义来对repr()返回的字符串中的非ASCII字符进行转义。

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

>>> 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'

如果必须对所有内容都具有\\uhhhh ,则必须进行自己的转换:

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)

上述功能并不像加引号ascii()函数的作用:

>>> 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

请注意,不将\\替换为\\\\是不可逆的; 例如。 您不知道实际的字符串是'好' (一个字符)还是'\\\好' (ASCII范围内的6个字符),因为两者都会产生\好作为输出。 Martijn的建议进行反斜杠替换,并且是可逆的。

您可以自己进行转换:

def unicodeescape(s):
    return ''.join(c if ord(c) < 128 else '\\u%04x' % ord(c) for c in s)

print(unicodeescape('你好'))

(Martijn关于BMP以外字符的说明仍然适用)

如果您想对程序输出的所有内容执行此操作,并且试图记住通过转换函数传递所有内容似乎并不是您的好时机,那么您也可以尝试执行以下操作:

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('你好')

这将创建一个自定义编码错误处理程序,该处理程序通过将有问题的字符替换为Unicode转义符来处理UnicodeEncodeErrors。 您可以像'你好'.encode('ascii', 'unicodeescapereplace')类的方式使用它,或者像上面的示例一样,将stdout替换为自动将其用于所有编码的stdout。

正常表示是使用Martijn Pieters解释的内置ascii获得的。

如果您确实想恒定地打印\\ u转义符,可以手动进行

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))

给出预期:

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

注意:我确实知道eval是邪恶的,但是在特定的用例中,我知道内部字符串不包含'并且用'括起来,因此它不能仅仅是编码字符的转换-但我永远不会做在外部字符串上至少不测试t.contains("'") ...

NB2:这种方法不能正确处理其代码是大于0xFFFF字符- 如果否则它会需要另一个...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM