格式化 Unicode 的 Unicode 表示?
Unicode representation to formatted Unicode?
我在理解 unicode 表达式到各自字符的翻译时遇到了一些困难。我一直在查看 unicode 规范,我遇到过各种格式如下 U+1F600
的字符串。据我所知,似乎没有内置函数知道如何将这些字符串转换为 Python 的正确格式,例如 \U0001F600
。
在我的程序中,我制作了一个小的正则表达式,它将找到这些 U\+.{5}
模式并将 U+
替换为 \U000
。但是,我发现此语法对于所有 unicode 字符都不相同,例如实际上应该从 U+200D
转换为 \u200D
的零宽度连接。
因为我不知道正确的 unicode 转义序列的每个变体,处理这种情况的最佳方法是什么?是我只能检查有限数量的这些特殊字符,还是我完全以错误的方式处理这个问题?
Python 版本为 2.7.
我认为您最可靠的方法是将数字解析为整数,然后使用 unichr
查找该代码点:
unichr(0x1f600) # or: unichr(int('1f600', 16))
注:上Python3,就是chr
。
您可以查看 json
模块实现。好像没那么简单:
# Unicode escape sequence
uni = _decode_uXXXX(s, end)
end += 5
# Check for surrogate pair on UCS-4 systems
if sys.maxunicode > 65535 and \
0xd800 <= uni <= 0xdbff and s[end:end + 2] == '\u':
uni2 = _decode_uXXXX(s, end + 1)
if 0xdc00 <= uni2 <= 0xdfff:
uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
end += 6
char = unichr(uni)
(来自 cpython-2.7.9/Lib/json/decoder.py 129-138 行)
我认为直接使用json.loads
会更容易:
>>> print json.loads('"\u0123"')
ģ
U+NNNN
只是用来谈论 Unicode 的常用符号。 Python 单个 Unicode 字符的语法是以下之一:
u'\xNN'
对于 Unicode 字符到 U+00FF
u'\uNNNN'
Unicode 字符通过 U+FFFF
u'\U00NNNNNN'
Unicode 字符到 U+10FFFF(最大)
注:N
为十六进制数。
输入字符时使用正确的符号。即使对于低字符,您也可以使用更长的符号:
u'A' == u'\x41' == u'\u0041' == u'\U00000041'
以编程方式,您还可以使用 unichr(n)
(Python 2) 或 chr(n)
(Python 3) 生成正确的字符。
请注意,在 Python 3.3 之前,Python 有 narrow 和 wide Unicode 版本。 unichr/chr
只能支持 sys.maxunicode
,在窄版本中为 65535 (0xFFFF),在宽版本中为 1114111 (0x10FFFF)。 Python 3.3 统一了构建并解决了 Unicode 的许多问题。
如果您正在处理 U+NNNN
格式的文本字符串,这里是一个正则表达式 (Python 3)。它查找 U+
和 4-6 个十六进制数字,并将它们替换为 chr()
版本。请注意,ASCII 字符 (Python 2) 或可打印字符 (Python 3) 将显示实际字符而不是转义版本。
>>> re.sub(r'U\+([0-9A-Fa-f]{4,6})',lambda m: chr(int(m.group(1),16)),'testing U+1F600')
'testing \U0001f600'
>>> re.sub(r'U\+([0-9A-Fa-f]{4,6})',lambda m: chr(int(m.group(1),16)),'testing U+5000')
'testing \u5000'
>>> re.sub(r'U\+([0-9A-Fa-f]{4,6})',lambda m: chr(int(m.group(1),16)),'testing U+0041')
'testing A'
>>> re.sub(r'U\+([0-9A-Fa-f]{4,6})',lambda m: chr(int(m.group(1),16)),'testing U+0081')
'testing \x81'
我在理解 unicode 表达式到各自字符的翻译时遇到了一些困难。我一直在查看 unicode 规范,我遇到过各种格式如下 U+1F600
的字符串。据我所知,似乎没有内置函数知道如何将这些字符串转换为 Python 的正确格式,例如 \U0001F600
。
在我的程序中,我制作了一个小的正则表达式,它将找到这些 U\+.{5}
模式并将 U+
替换为 \U000
。但是,我发现此语法对于所有 unicode 字符都不相同,例如实际上应该从 U+200D
转换为 \u200D
的零宽度连接。
因为我不知道正确的 unicode 转义序列的每个变体,处理这种情况的最佳方法是什么?是我只能检查有限数量的这些特殊字符,还是我完全以错误的方式处理这个问题?
Python 版本为 2.7.
我认为您最可靠的方法是将数字解析为整数,然后使用 unichr
查找该代码点:
unichr(0x1f600) # or: unichr(int('1f600', 16))
注:上Python3,就是chr
。
您可以查看 json
模块实现。好像没那么简单:
# Unicode escape sequence
uni = _decode_uXXXX(s, end)
end += 5
# Check for surrogate pair on UCS-4 systems
if sys.maxunicode > 65535 and \
0xd800 <= uni <= 0xdbff and s[end:end + 2] == '\u':
uni2 = _decode_uXXXX(s, end + 1)
if 0xdc00 <= uni2 <= 0xdfff:
uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
end += 6
char = unichr(uni)
(来自 cpython-2.7.9/Lib/json/decoder.py 129-138 行)
我认为直接使用json.loads
会更容易:
>>> print json.loads('"\u0123"')
ģ
U+NNNN
只是用来谈论 Unicode 的常用符号。 Python 单个 Unicode 字符的语法是以下之一:
u'\xNN'
对于 Unicode 字符到 U+00FFu'\uNNNN'
Unicode 字符通过 U+FFFFu'\U00NNNNNN'
Unicode 字符到 U+10FFFF(最大)
注:N
为十六进制数。
输入字符时使用正确的符号。即使对于低字符,您也可以使用更长的符号:
u'A' == u'\x41' == u'\u0041' == u'\U00000041'
以编程方式,您还可以使用 unichr(n)
(Python 2) 或 chr(n)
(Python 3) 生成正确的字符。
请注意,在 Python 3.3 之前,Python 有 narrow 和 wide Unicode 版本。 unichr/chr
只能支持 sys.maxunicode
,在窄版本中为 65535 (0xFFFF),在宽版本中为 1114111 (0x10FFFF)。 Python 3.3 统一了构建并解决了 Unicode 的许多问题。
如果您正在处理 U+NNNN
格式的文本字符串,这里是一个正则表达式 (Python 3)。它查找 U+
和 4-6 个十六进制数字,并将它们替换为 chr()
版本。请注意,ASCII 字符 (Python 2) 或可打印字符 (Python 3) 将显示实际字符而不是转义版本。
>>> re.sub(r'U\+([0-9A-Fa-f]{4,6})',lambda m: chr(int(m.group(1),16)),'testing U+1F600')
'testing \U0001f600'
>>> re.sub(r'U\+([0-9A-Fa-f]{4,6})',lambda m: chr(int(m.group(1),16)),'testing U+5000')
'testing \u5000'
>>> re.sub(r'U\+([0-9A-Fa-f]{4,6})',lambda m: chr(int(m.group(1),16)),'testing U+0041')
'testing A'
>>> re.sub(r'U\+([0-9A-Fa-f]{4,6})',lambda m: chr(int(m.group(1),16)),'testing U+0081')
'testing \x81'