2

奇妙なエスケープされたユニコード文字列に問題があります。私のスクリプトは、リクエスト ライブラリを介して 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

問題は、\u003c のような二重エスケープされた Unicode シーケンスです。\u003c は通常 < char を表します。\xd6 は正しく、ドイツ語の Ö を表します。この二重エスケープは、私のユニコード文字列を完全に台無しにします:-)

この投稿で同様の問題を発見しました: Stack Overflow - Conversion of strings like \uXXXX in python

string.decode('unicode-escape') を使用した解決策は、すべての Unicode シーケンスがエスケープされ、単一エスケープと二重エスケープが混在している場合にのみ機能するようです。ダブルエスケープをシングルエスケープに置き換えるだけで、Unicode 文字列が破損します。

最も簡単で最善の解決策は、サーバー側で応答エンコーディングを調整することですが、アクセスできません...

ご協力いただきありがとうございます!!!

4

1 に答える 1

6

サーバーが 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

正規表現のアプローチは、両方の例をデコードします (2 番目が最初にデコードされます)。

>>> 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 ?>
于 2012-12-17T16:41:51.963 に答える