如何離線查找或轉換Unicode字碼指標— PowerShell小妙用

Chris K.Y. Fung
數碼文明推廣教室
6 min readJun 23, 2023

--

將文字轉變成 Unicode 字碼可以避免產生亂碼或錯誤,讓不同的語言和系統都能正確處理文字資料。例如,使用 Unicode 字碼儲存文字資料,就可以避免編碼不一致造成的資料損毀或查詢錯誤。

什麼是 Unicode 字碼指標 (Code Point)?

字碼指標,亦稱作「字碼點」或「代碼點」。簡單來說,就是一種用數字表示不同文字的方法。例如,中文字「漢」的 Unicode 字碼指標是 U+6F22。如果你想知道某個文字的 Unicode 字碼指標,你可以在網上查找,或者使用如 中文到Unicode (chineseconverter.com) 的線上轉換器。

使用 PowerShell 將 UTF-8 字串轉換成 Unicode 字碼

除了線上轉換器,還有很多工具可以用來轉換文字編碼。然而,萬一遇上無法連線上網又沒有在電腦上安裝工具的情況,在 Windows 10/11 上你只須要簡單的 PowerShell 命令就能幫你計算出答案。

方法一:UTF-32 編碼和解碼

PowerShell 可以調用 Windows 中的 System.Text.Encoding 類別進行編碼,使用 Encoding.GetBytes() 方法將一組 Unicode 字元轉換成位元組序列的處理程序,接著利用 System.BitConverter 類別的 ToUInt32() 方法轉換成整數,最後格式化輸出為 0x 開頭的 32位 Unicode 字碼指標。

以下是將 Emoji 表情符號 😀(微笑)轉換成字碼指標的範例:

PS > $utf32bytes = [System.Text.Encoding]::UTF32.GetBytes("😀")
PS > $codePoint = [System.BitConverter]::ToUint32($utf32bytes, 0)
PS > "0x{0:X}" -f $codePoint

0x1F600 #輸出結果

還原為文字

既然能夠完成字元到 Unicode 字碼指標的轉換,那麼反過來,該怎麼做呢?

如果是一個 0x 開頭的 Unicode 字碼指標,你可以在 PowerShell 週用在Window 系統中 [char] 結構 ConvertFromUtf32() 方法將它轉換成對應的字符:

PS > [char]::ConvertFromUtf32(0x1F600)

😀 #輸出結果

方法二:UTF-16 編碼和解碼

遇到某些程式不支援 UTF-32 編碼,就不能夠用上述的方法來處理。你可以改為使用以下的方法,將字符轉為 UTF-16 字碼指標和代理對 (surrogate pair)。這個方法所用的都是最基本的指令,可以全部塞在同一行裡,更簡潔且易記。

以下的範例,會將 😀 轉換成 \u 開頭的 UTF-16 代理對:

PS > "😀".ToCharArray() | ForEach-Object { "\u" + ([int]$_).ToString("x4") }

"\u" + ([int][char]"😀").ToString("x4")

# 以下是輸出結果
\ud83d
\ude00

這個命令會首先將文字轉換成字元陣列,然後計算出每一個字元的十六進位數字並加上 \u 的標頭。

而且,不僅能夠轉換單個字符,更可以處理字串,轉換出每個字符所對應的字碼指標。以下是對中文字串「你好」進行轉換的範例:

PS > "你好".ToCharArray() | ForEach-Object { "\u" + ([int]$_).ToString("x4") }

# 以下是輸出結果
\u4F60 # 你
\u597D # 好

批量將字串轉換成 Unicode 字碼

若你想將多個字串轉換成對應的 Unicode 字碼,可以參考以下的範例:

$Strings = @("一", "二三", "45六")

$Strings | ForEach-Object {
$Escaped = ($_.ToCharArray() | ForEach-Object {
if ($_ -gt 127) {
"\u" + ([int]$_).ToString("x4")
} else {
$_
}
}) -join ""

[PSCustomObject]@{
String = $_
PointCode = $Escaped
}
} | Format-List

這個 PowerShell 腳本會通過巢狀迴圈,將在第一行 $Strings = @() 的括號內列出的字串陣列逐一進行轉換,並最後將全部結果一併列出。而且,做了一些小修改只轉換並非 ASCII 的字元。以下是這個範例的輸出結果:

# 以下是輸出結果

String : 一
PointCode : \u4e00

String : 二三
PointCode : \u4e8c\u4e09

String : 45六
PointCode : 45\u516d

還原為文字

如果你有一組 UTF-16 字碼,想還原成文字。這時候,可在 PowerShell 利用 Windows 中的 System.Text.RegEx 類別的 Unescape() 方法,將 \u 開頭的Unicode 字碼指標序列成對應的字串。例如:

PS > [regex]::Unescape('\u4F60\u597D')

你好 #輸出結果

注意,這裡的 Unicode 字碼指標必須是 4 個位的十六進位 (Hex) 數字,如果不足 4 個位,需要在前面補零。如果超過 4 個位數,例如 😀 的字碼指標是的 Hex 是 1F600,若將這個字碼指標塞進 Unescape() 方法,將會產生錯誤的結果:

PS > [regex]::Unescape('\u1F600')

ὠ0 #輸出結果

要獲得正確的輸出,需要使用 UTF-16 代理對,並將 Hex 數字分成兩個 \u 開頭的 4 位數編碼代入 Unescape() 方法:

PS > [regex]::Unescape('\uD83D\uDE00')

😀 #輸出結果

如果你想知道如何將一個超過 4 位數的 Unicode 字碼指標分成代理對,你可以參考 Unicode — Surrogate pair (UTF-16) (datacadamia.com) 這個網站。

好了,希望你們會用得著這些 PowerShell 的技巧。謝謝你們的閱讀,下次見!

如果您喜歡這篇文章,請為此文章 👏 👏 👏 👏 👏 👏 👏,並分享至你的 Facebook 及 Twitter。

你可能也會想知道… 👀

若有任何疑問或建議,歡迎標註留言或透過 Facebook 專頁 聯繫我 🙂

--

--

Chris K.Y. Fung
數碼文明推廣教室

📝集中分享提升生產力、自動化至開發等技能📢📈 博客及開發人員,於香港理工大學MPhil畢業,並多年在大學從事學術研究,喜歡學習多元化知識和技術。歡迎訂閱・標註回應,共享交流啟發性話題🐱‍🏍 about.me/chriskyfungfb.com/chriskyfung 😪📘