0

我正在尝试编写一个 python 实现,java.util.Properties其要求将 unicode 字符以以下格式写入输出文件\u####

(如果您好奇,文档就在这里,尽管它对这个问题并不重要:http: //docs.oracle.com/javase/6/docs/api/java/util/Properties.html

我基本上需要通过以下测试用例的东西

def my_encode(s):
    # Magic

def my_decode(s):
    # Magic

# Easy ones that are solved by .encode/.decode 'unicode_escape'
assert my_decode('\u2603') == u'☃'
assert my_encode(u'☃') == '\\u2603'

# This one also works with .decode('unicode_escape')
assert my_decode('\\u0081') == u'\x81'
# But this one does not quite produce what I want
assert my_encode(u'\u0081') == '\\u0081' # Instead produces '\\x81'

请注意,我已经尝试过unicode_escape,它接近但并不能完全满足我想要的

我注意到simplejson这种转换正确:

>> simplejson.dumps(u'\u0081')
'"\\u0081"'

但我宁愿避免:

  1. 重新发明轮子
  2. 对 simplejson 的输出进行一些粗略的子串化
4

1 回答 1

3

根据您链接到的文档:

属性键或值中小于\u0020和大于字符的字符按照相应的十六进制值写入。\u007E\uxxxxxxxx

因此,这很容易转换为 Python:

def my_encode(s):
    return ''.join(
        c if 0x20 <= ord(c) <= 0x7E else r'\u%04x' % ord(c)
        for c in s
    )

对于字符串中的每个字符,如果代码点在 0x20 和 0x7E 之间,则该字符保持不变;否则,\u使用编码为 4 位十六进制数字的代码点。该表达式c for c in s是一个生成器str.join表达式,因此我们使用空字符串将其转换回字符串。

对于解码,您可以使用unicode_escape您提到的编解码器:

def my_decode(s):
    return s.decode('unicode_escape')
于 2013-09-30T04:51:13.587 回答