如何将非 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()
function:
将字符串转换为调试表示,将非 ASCII、不可打印的字符转换为转义序列
As repr()
, return a string containing a printable representation of an object, but escape the non-ASCII characters in the string returned by repr()
using \x
, \u
or \U
escapes.
对于 U+0100-U+FFFF 范围内的 Unicode 代码点,这使用 \uhhhh
转义;对于 Latin-1 范围 (U+007F-U+00FF),使用 \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
请注意,如果不将 \
替换为 \
,您想要的是不可逆的;例如。您无法知道实际字符串是 '好'
(一个字符)还是 '\u597d'
(ascii 范围内的 6 个字符),因为两者都会产生 \u597d
作为输出。 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')
一样使用它,或者像上面的示例一样,将标准输出替换为自动使用它进行所有编码的标准输出。
正常表示是通过使用 ascii
内置函数获得的,正如 Martijn Pieters 所解释的那样。
如果你真的想不断打印 \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 的字符 - 它需要另一个 if else...
# what I currently have
print('你好')
# 你好
# this is what I want
print('你好')
# \uXXXX \uXXXX
我该怎么做?我想将字符串中的所有非 ascii 字符打印为 unicode 转义文字
您可以使用 ascii()
function:
As
repr()
, return a string containing a printable representation of an object, but escape the non-ASCII characters in the string returned byrepr()
using\x
,\u
or\U
escapes.
对于 U+0100-U+FFFF 范围内的 Unicode 代码点,这使用 \uhhhh
转义;对于 Latin-1 范围 (U+007F-U+00FF),使用 \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
请注意,如果不将 \
替换为 \
,您想要的是不可逆的;例如。您无法知道实际字符串是 '好'
(一个字符)还是 '\u597d'
(ascii 范围内的 6 个字符),因为两者都会产生 \u597d
作为输出。 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')
一样使用它,或者像上面的示例一样,将标准输出替换为自动使用它进行所有编码的标准输出。
正常表示是通过使用 ascii
内置函数获得的,正如 Martijn Pieters 所解释的那样。
如果你真的想不断打印 \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 的字符 - 它需要另一个 if else...