Java中解码Python编码的utf-8字符串\xc4\x91

6

如何从Python创建的字符串“Oslobo\xc4\x91enja”获取正确的Java字符串?如何解码它?我已经尝试了所有可能的方法,到处寻找答案,但是我已经被这个问题困扰了2天。请帮助我!

以下是Python的Web服务方法,它返回JSON数据,Java客户端使用Google Gson进行解析。

def list_of_suggestions(entry):
   input = entry.encode('utf-8')
   """Returns list of suggestions from auto-complete search"""
   json_result = { 'suggestions': [] }
   resp = urllib2.urlopen('https://maps.googleapis.com/maps/api/place/autocomplete/json?input=' + urllib2.quote(input) + '&location=45.268605,19.852924&radius=3000&components=country:rs&sensor=false&key=blahblahblahblah')
   # make json object from response
   json_resp = json.loads(resp.read())

   if json_resp['status'] == u'OK':
     for pred in json_resp['predictions']:
        if pred['description'].find('Novi Sad') != -1 or pred['description'].find(u'Нови Сад') != -1:
           obj = {}
           obj['name'] = pred['description'].encode('utf-8').encode('string-escape')
           obj['reference'] = pred['reference'].encode('utf-8').encode('string-escape')
           json_result['suggestions'].append(obj)

   return str(json_result)

这里是Java客户端的解决方案

private String python2JavaStr(String pythonStr) throws UnsupportedEncodingException {
    int charValue;
    byte[] bytes = pythonStr.getBytes();
    ByteBuffer decodedBytes = ByteBuffer.allocate(pythonStr.length());
    for (int i = 0; i < bytes.length; i++) {
        if (bytes[i] == '\\' && bytes[i + 1] == 'x') {
            // \xc4 => c4 => 196
            charValue = Integer.parseInt(pythonStr.substring(i + 2, i + 4), 16);
            decodedBytes.put((byte) charValue);
            i += 3;
        } else
            decodedBytes.put(bytes[i]);
    }
    return new String(decodedBytes.array(), "UTF-8");
}

1
你有UTF-8数据显示为Python字符串文字,将其解码为Unicode会得到Oslobođenja。 Java应该可以处理UTF-8数据吧? - Martijn Pieters
1
也许可以看一下这个问题:https://dev59.com/TG025IYBdhLWcg3wi2qw - Freelancer
1
@Ognjen:你想做什么?如果你在Python中加载JSON,那么u'Oslobo\u0111enja'就是你想要的。这是一个有效的Unicode值。我认为你正在生成JSON供一些Java代码读取,并且正在努力解决Java方面的问题。 - Martijn Pieters
1
请勿在问题标题中加入“已解决”;相反,您可以将任何一个答案标记为被采纳的答案。 - Martijn Pieters
1
@Ognjen:JSON也使用\u....转义码,任何JSON解析器都可以处理。而是u'..'u"..."字符串对于这些解析器无效。 - Martijn Pieters
显示剩余17条评论
2个回答

2

您正在返回Python数据结构的字符串版本。

相反,应返回实际的JSON响应;保留值为Unicode:

if json_resp['status'] == u'OK':
    for pred in json_resp['predictions']:
        desc = pred['description'] 
        if u'Novi Sad' in desc or u'Нови Сад' in desc:
            obj = {
                'name': pred['description'],
                'reference': pred['reference']
            }
            json_result['suggestions'].append(obj)

return json.dumps(json_result)

现在Java不必解释Python转义码,而是可以解析有效的JSON。


正如你们英语使用者所说:运行得很好! :) 谢谢,这是一种更优雅的解决方案。我仍在学习Python。 - Ognjen Stanić

1
Python通过将UTF-8字节转换为一系列\xVV值来转义Unicode字符,其中VV是字节的十六进制值。这与Java Unicode转义非常不同,后者仅针对每个字符使用单个\uVVVV,其中VVVV是十六进制的UTF-16编码。

考虑以下内容:

\xc4\x91

以十进制表示,这些十六进制值分别为:

196 145

然后(在Java中):
byte[] bytes = { (byte) 196, (byte) 145 };
System.out.println("result: " + new String(bytes, "UTF-8"));

打印:

result: đ

非常感谢你!我请你喝啤酒,把账单发给我 :) 再次感谢! - Ognjen Stanić

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接