依字位 (grapheme) 處理字串

以前在處理字串的時候, 不管是反轉或是取字元都沒考慮到有些語言的一個字母可能是由多個字組成的, 直到遇到問題.

舉個越南文的例子, 是由 ơ (%cc%9b) 組成的, 所以處理的時候就容易有預料外的結果, 以字串反轉來說, ơa 反轉後變成 a̛o

關於 Grapheme 與相關

這部分沒有仔細研究, 但是網路資源很多可以需要時知道細節時再查詢.

使用 TextElementEnumerator 處理字串

使用 TextElementEnumerator 就能正確的將 ơa 反轉成 ơa 了.

1
2
3
4
5
6
7
8
9
10
11
12
using System.Globalization;
public string ReverseGraphemeClusters(string s)
{
TextElementEnumerator enumerator = StringInfo.GetTextElementEnumerator(s);
StringBuilder sb = new StringBuilder();
while (enumerator.MoveNext())
{
sb.Insert(0, enumerator.GetTextElement());
}

return sb.ToString();
}

結論

就是個沒遇到不會想到的問題, 處理方式也很簡單, 只是背後細節要看很多文件才能了解很麻煩所以乾脆紀錄一下備查.

參考

What’s the difference between a character, a code point, a glyph and a grapheme?
Glossary of Unicode Terms
Correctly reversing a string
C# grapheme