在.NET中正確的計算出字串的長度
網際網路時至今日,早已經是一個地球村的概念,所有的資訊透過網際網路飛快的傳遞,讓語言的使用率與能見度都達到前所未有的境界,以目前來說全世界大概是對UTF-8
編碼有共識,絕大部分的網站都是採用UTF-8編碼,而.NET內建的文字編碼是UTF-16
,也就是說所有的文字在處理的過程中,都會以UTF-16
來識別處理。
字串長度(文字長度)的基本計算 / String.Length
有些時刻我們必須針對字串進行長度計算,通常用於報表
或是填補字串 Pad
上,錯誤的字元數量計算可能會造成錯誤的結果,而偏偏進入到Unicode
時代後,中文字的編碼是以一種變動的型態來進行編碼,有些常用的中文字元落在BMP(Basic Multilingual Plane),那麼就可以被正確的計算成一個字,例如:張
的UTF-16編碼是0x5F35
。而有些罕見自可能會若在SIP(Supplementary Ideographic Plane),那麼這時候C#採用String.Length計算就會出錯,被計算成兩個字元。例如:𡩋
的UTF-16編碼是0xD846 0xDE4B
。
字串長度(文字長度)的仔細計算
可以使用.NET的System.Globalization.StringInfo
類別來輔助,程式碼如下:
string cDemo = "張鈞𡩋";
Console.WriteLine($"錯誤的長度:{cDemo.Length}");
var oSI = new System.Globalization.StringInfo(cDemo);
Console.WriteLine($"正確的長度:{oSI.LengthInTextElements}");
輸出的結果:
錯誤的長度:4 //𡩋的長度算錯了
正確的長度:3
透過上面的方法,可以更精準的計算出中文字
正確的長度,就算是中英文混雜
也適用。但倘落涉及到使用到菲茨派屈克修飾符(EMOJI MODIFIER FITZPATRICK)的Emojis,那麼計算就可能又變得不正確了。不過這個問題還好,畢竟沒有人會用Emojis當作名字吧?(好啦,或許未來有可能)
string cDemo = "🍖🧒🏿";
Console.WriteLine($"錯誤的長度:{cDemo.Length}");
var oSI = new System.Globalization.StringInfo(cDemo);
Console.WriteLine($"正確的長度:{oSI.LengthInTextElements}");
輸出的結果:
錯誤的長度:6
正確的長度:3
從上面的輸出結果發現很顯然是錯誤的,正確的長度應該是2才對。🍖
其實有被正確的計算成1
。但是🧒🏿
因為涉及到修飾符,所以計算就錯誤了,被錯誤的計算成2
。
相關參考
- Emojis Icon Full List 表情符號全列表
- The Absolute Minimum Every Software Developer Must Know About Unicode in 2023 (Still No Excuses!)