簡體   English   中英

ValueError:在讀取json文件時解碼“字符串”時未配對的高代理

[英]ValueError: Unpaired high surrogate when decoding 'string' on reading json file

我目前正在研究 python 3.8.6。 在 python 中讀取(數千個)json 文件時出現以下錯誤:

ValueError: Unpaired high surrogate when decoding 'string' on reading json file

我在檢查其他 stackoverflow 帖子時嘗試使用以下解決方案,但沒有任何效果:

1) import json
   json.loads('{"":"\\ud800"}')

2) import simplejson
   simplejson.loads('{"":"\\ud800"}')

問題是在收到此錯誤后,不會讀取剩余的 json 文件。 有沒有辦法擺脫這個錯誤,這樣我就可以讀取所有的 json 文件?

我不確定需要提供哪些有關該問題的所有信息,因此請隨時提問。

Unicode 代碼點 U+D800可能僅作為代理對的一部分出現(並且僅在 UTF-16 編碼中)。 因此,JSON 中的字符串(解碼后)不是有效的 UTF-8。

JSON 本身可能有效,也可能無效。 規范沒有提到不匹配代理對的情況,但明確允許不存在的代碼點:

要轉義不在基本多語言平面中的代碼點,可以將字符表示為十二個字符的序列,對與代碼點對應的 UTF-16 代理對進行編碼。 因此,例如,僅包含 G 譜號字符 (U+1D11E) 的字符串可以表示為“\?\?”。 但是,JSON 文本的處理器是將此類代理對解釋為單個代碼點還是顯式代理對是由特定處理器確定的語義決定。

請注意,JSON 語法允許 Unicode 當前不提供字符分配的代碼點。

現在,你可以選擇你的朋友,但你不能選擇你的家人,你也不能總是選擇你的 JSON。 所以下一個問題是:如何解析這個爛攤子?

看起來 Python(3.9 版)和simplejson (3.17.2 版)中的內置json模塊在解析 JSON 時都沒有問題。 只有在您嘗試使用字符串時才會出現此問題。 所以這真的與 JSON 沒有任何關系:

>>> bork = '\ud800'
>>> bork
'\ud800'
>>> print(bork)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'utf-8' codec can't encode character '\ud800' in position 0: surrogates not allowed

幸運的是,我們可以手動編碼字符串並告訴 Python 如何處理錯誤。 例如,將錯誤的代碼點替換為問號:

>>> bork.encode('utf-8', errors='replace')
b'?'

該文檔列出了errors參數的其他可能選項

為了修復這個損壞的字符串,我們可以編碼(到bytes )然后解碼(回到str ):

>>> bork.encode('utf-8', errors='replace').decode('utf-8')
'?'

孤立的 Unicode 代理不對應任何東西。 每個有效的高代理代碼點都需要緊跟一個低代理代碼點,然后才能對其進行有意義的解碼。

錯誤消息僅表示此代碼點孤立地沒有明確定義的含義。 這就像說“拿”而不說我們應該拿什么,或者“看”而不填寫句子的賓語。

你不應該在不包含 UTF-16 的文件中使用代理; 它們是為這種編碼嚴格保留的。 它用於對 16 位空間之外的字符進行編碼,這種 16 位編碼可以通過將它們分成兩個代碼點來自然地表示。

簡單而明顯的解決方法是提供缺失的信息,但我們不知道它是什么。 也許您有更多上下文,並且可以填寫正確的低代理對。 但例如,這有效:

>>> json.loads('{"":"\\ud800\\udc00"}')
{'': '𐀀'}

它使用單個代碼點U+010000填充 JSON,但當然我們不知道這是否實際上是您的數據應該包含的代碼點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM