如何離線查找或轉換Unicode字碼指標— PowerShell小妙用
將文字轉變成 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。
你可能也會想知道… 👀
- 8個 PowerShell 操作 Windows、文件、網頁的例子 | 數碼文明推廣教室 | Medium
- 分享幾個在 Windows 與 Linux 常見的編碼問題與解決方案 | The Will Will Web (miniasp.com)
若有任何疑問或建議,歡迎標註留言或透過 Facebook 專頁 聯繫我 🙂