【问题标题】:python mixed single and double unicode escape sequencespython混合单双unicode转义序列
【发布时间】:2012-12-18 04:39:12
【问题描述】:

我对奇怪的转义 unicode 字符串有一些问题。我的脚本通过请求库使用 Web 服务,并且 response.text 包含以下 unicode 字符串:

 u'\\u003c? abc ?\\u003eDas Modell des Adaptiven Zyklus wurde aus vergleichenden Untersuchungen zur Dynamik von \xd6kosystemen abgeleitet.\\u003c? /abc ?\\u003e'

 **Updated** Martijn solution works with the upper one, but breaks with this one because of len="12"
 u'\\u003c?abc len="12"?\\u003eResilienz sollte als st\xe4ndiger Anpassungsprozess zwischen Systemen und der Umwelt begriffen werden.\\u003c? /abc ?\\u003e'

来自服务器的响应如下所示:

\u003c? abc ?\u003eDas Modell des Adaptiven Zyklus wurde aus vergleichenden Untersuchungen zur Dynamik von Ökosystemen abgeleitet.\u003c?dpf /sent ?\u003e

问题是双重转义的 unicode 序列,如 \u003c,\u003c 通常表示

我在这篇文章中发现了类似的问题: Stack Overflow - Conversion of strings like \uXXXX in python

使用 string.decode('unicode-escape') 的解决方案似乎只有在所有 unicode 序列都被转义但不能混合单双转义的情况下才有效。只需用单个转义符替换双重转义符就会给我一个损坏的 unicode 字符串。

最简单和最好的解决方案是调整服务器端的响应编码,但我无权访问...

感谢您的帮助!!!

【问题讨论】:

  • 出于好奇,这些响应的内容类型标头是什么?
  • 内容类型:文本/纯文本; charset=UTF-8
  • @Martijn Pieters 我尝试了firebug控制台中的字符串,输出似乎是正确的:var a = '\u003c? abc len="12" ?\u003eDas Modell des Adaptiven Zyklus wurde aus vergleichenden Untersuchungen zur Dynamik von Ökosystemen abgeleitet.\u003c?dpf /sent ?\u003e'; console.log(a); Strange things...
  • 您的第二个示例包含额外的引号,使其作为文字 JSON 值无效。请参阅我的更新答案。

标签: python unicode


【解决方案1】:

我怀疑服务器正在返回 JSON 字符串。 JSON 使用相同的转义序列,如果您在字符串 json.loads() 周围添加引号,则非常乐意为您解码该示例:

>>> txt = u'\\u003c? abc ?\\u003eDas Modell des Adaptiven Zyklus wurde aus vergleichenden Untersuchungen zur Dynamik von \xd6kosystemen abgeleitet.\\u003c? /abc ?\\u003e'
>>> content = txt.encode('utf8')
>>> content
'\\u003c? abc ?\\u003eDas Modell des Adaptiven Zyklus wurde aus vergleichenden Untersuchungen zur Dynamik von \xc3\x96kosystemen abgeleitet.\\u003c? /abc ?\\u003e'
>>> import json
>>> json.loads('"{0}"'.format(content))
u'<? abc ?>Das Modell des Adaptiven Zyklus wurde aus vergleichenden Untersuchungen zur Dynamik von \xd6kosystemen abgeleitet.<? /abc ?>'
>>> print json.loads('"{0}"'.format(content))
<? abc ?>Das Modell des Adaptiven Zyklus wurde aus vergleichenden Untersuchungen zur Dynamik von Ökosystemen abgeleitet.<? /abc ?>

尝试使用json.loads('"{0}"'.format(response.content)) 将响应解码为Unicode。

您的更新版本确实包含引号,有点令人烦恼,因为必须转义这些引号才能在有效的 JSON 中使用。那么它可能不是 JSON,而是某种其他形式的转义; Java 和 Ruby 也使用 \uxxxx 转义。接下来我们可以尝试使用正则表达式来替换这些:

import re

uescapes = re.compile(r'(?<!\\)\\u[0-9a-fA-F]{4}', re.UNICODE)
def uescape_decode(match): return match.group().decode('unicode_escape')

uescapes.sub(uescape_decode, response.text)

这个正则表达式会将任何\uxxxx 匹配解码为其等效的Unicode 字符,前提是它前面没有\,它有效地转义了转义; \\uxxxx 不会被替换。

正则表达式方法会解码您的两个示例(先解码第二个):

>>> print uescapes.sub(uescape_decode, txt)
<?abc len="12"?>Resilienz sollte als ständiger Anpassungsprozess zwischen Systemen und der Umwelt begriffen werden.<? /abc ?>
>>> print uescapes.sub(uescape_decode, u'\\u003c? abc ?\\u003eDas Modell des Adaptiven Zyklus wurde aus vergleichenden Untersuchungen zur Dynamik von \xd6kosystemen abgeleitet.\\u003c? /abc ?\\u003e')
<? abc ?>Das Modell des Adaptiven Zyklus wurde aus vergleichenden Untersuchungen zur Dynamik von Ökosystemen abgeleitet.<? /abc ?>

【讨论】:

  • 谢谢!!!这是一个很好的提示!但我仍然有 json.loads 的问题:ValueError: Extra data: line 1 column 57 - line 1 column 283(char 57 认为我必须清理一些东西。认为你的答案解决了我的问题。如果我的东西解决了我'我很高兴接受它。到目前为止,谢谢。
  • @martin-pieters,您的回答完全正确。问题是,我提供了一个精简的 unicode 示例的简单版本。使用简单版本时,您的解决方案效果很好,但与更新后的版本不同。
  • @hetsch:使用正则表达式方法更新。
  • @Clearquestionwithexamples:它恰好在 Python 2.7 中工作,前提是你有一个 UCS-2 窄版本;在这种情况下,uescapes.sub(uescape_decode, '\ud861\ude00') 产生 u'\U00028600'
  • @Clearquestionwithexamples:在 UCS-4 构建中,您最终将代理对作为单独的代码单元:u'\ud861\ude00';编码为 UTF-16,然后再次解码,将它们解析为正确的非 BMP 代码点。
猜你喜欢
  • 1970-01-01
  • 2011-05-29
  • 2021-01-30
  • 1970-01-01
  • 1970-01-01
  • 2018-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多