DevTool 團隊

Unicode 解碼與亂碼自救:\u 轉義是什麼、怎麼還原

收到一串 \u4f60\u597d 或者 &#x 的字元看不懂?本文分清 \u 轉義、碼點、HTML 實體、URL 編碼四種形態,給出還原成中文的程式方法與線上工具,並講清 Emoji 代理對的坑。

先分清你手裡的亂碼是哪一種

「亂碼」不是一種東西,是四種。還原之前先看形態,形態決定方法:

形態 長什麼樣 它是什麼
Unicode 轉義 \u4f60\u597d 按碼點轉義,JSON / JS 原始碼 / 部分介面的預設輸出
碼點形式 U+4F60 或 4f60 字元在 Unicode 表裡的編號本身
HTML 實體 你 或 你 HTML 裡的字元參考,十六進位與十進位兩種寫法
URL 編碼 %E4%BD%A0%E5%A5%BD 按 UTF-8 位元組逐個百分號轉義,一個中文三個 %XX

\u4f60\u597d 解開是「你好」,你 解開也是「你」,%E4%BD%A0 解開還是「你」——同一批字元、三層編碼。混著出現(比如 URL 參數裡包著轉義過的 JSON)就一層一層剝。

方法一:線上工具,看不清形態時最省事

Unicode 編碼解碼工具支援上面四種形態的互轉,並帶兩個排查時特別有用的能力:

  1. 自動識別輸入格式——不確定手裡是轉義、實體還是百分號編碼時,直接貼上,它按特徵判斷;
  2. 字元詳情面板——每個字元的碼點、十進位、十六進位、UTF-8 位元組、分類資訊逐項列出,亂碼到底是編碼問題還是字型問題,看一眼詳情就能定位。

統計區即時顯示字元數與位元組數,「一列到底佔了多少位元組」這種問題不用再心算。轉換歷史存在本地,來回對比兩段文字時可以回翻。

方法二:用程式還原

知道資料來源、想嵌進指令碼裡處理時,兩行 code 的事。

JavaScript——JSON 裡的 \u 轉義在 JSON.parse 時自動解開:

JSON.parse('{"msg":"\\u4f60\\u597d"}').msg;  // "你好"

普通字串裡的轉義,console.log 本身就會渲染;要把任意字元反向轉成 \u 形式,charCodeAt(0).toString(16) 拼四位即可。

Python——unicode_escape 編解碼器專治這個:

s = r"\u4f60\u597d"
print(s.encode().decode("unicode_escape"))  # 你好

URL 編碼則是另一套:urllib.parse.unquote("%E4%BD%A0")。兩者經常疊著出現,先解外層再解內層。

反向:什麼時候需要「編碼」而不是解碼

  • 介面或設定檔只接受 ASCII,中文明文過不去——整段轉成 \u 轉義;
  • 要在 HTML 裡安全展示特殊字元(<、&、不可見字元)——轉 HTML 實體;
  • 拼接 URL 參數——中文必須百分號編碼,否則請求直接報錯;
  • 排查「這個字元到底是什麼」——轉成碼點形式,去 Unicode 表裡查它的分類與名稱。

本站工具的輸入輸出一鍵交換,反向操作不用換工具。

Emoji 與代理對:逐字解碼的坑

「😀」的碼點是 U+1F600,超出了 U+FFFF。UTF-16 用一對代理項表示它:\ud83d\ude00。問題來了:

  • 逐字元解碼的簡易工具會把這對代理拆成兩個「字元」,輸出兩個問號或兩個方塊;
  • 按碼點逐個統計的程式會把一個 Emoji 數成 2 個字元;
  • 字串截斷如果切在代理對中間,前後都會爛。

判斷一個工具能不能信,丟一個 Emoji 進去就知道了。本站的轉換按代理對正確處理,U+FFFF 以上的字元不會被拆碎;字元統計同樣按完整字元計數。

常見問題

\u4f60\u597d 這種字串是什麼編碼?

這是 Unicode 轉義序列,每個 \u 後跟四個十六進位,表示一個字元的碼點。\u4f60\u597d 解碼後就是「你好」。它常見於 JSON、JavaScript 原始碼和部分介面回應,本質仍是 UTF-8 文字,只是把非 ASCII 字元寫成了轉義形式。

為什麼有的 Emoji 解碼後會變成兩個字元?

因為它們超出了基本多文種平面(U+FFFF 以上),UTF-16 裡要用一對代理項(Surrogate Pair)表示,佔兩個碼點位置。逐字解碼的工具會把一個 Emoji 拆成兩個亂碼字元;支援代理對的工具能正確合併還原。

\u 轉義和百分號編碼(%E4%BD%A0)是一回事嗎?

不是。\u 轉義按碼點表示字元;百分號編碼是 URL 編碼,按 UTF-8 位元組逐個轉義,一個中文通常是三個 %XX。兩者經常同時出現在同一段資料裡,但編碼層級不同,解碼順序也不同。

怎麼把一段文字反向編碼成 \u 轉義形式?

在 Python 裡用 "你好".encode("unicode_escape"),或本站工具的編碼方向一鍵得到;JavaScript 裡 JSON.stringify 對非 ASCII 字元預設就會輸出 \u 轉義。介面只收轉義形式、或要壓縮非 ASCII 字元可見度時用得上。

線上解碼會把內容傳到伺服器嗎?

本站的 Unicode 轉換在瀏覽器本地完成,輸入不離開裝置,轉換歷史也只存在瀏覽器裡。使用其他線上工具前應確認其資料處理方式,含敏感內容的文字尤其要注意。

相關閱讀