🧑🤝🧑
【C#】サロゲートペア文字のカウント方法
結論
サロゲートペア文字をカウントする際は、 StringInfo.LengthInTextElements
プロパティを使用します。
//サロゲートペアで構成された文字列
string str = "𠀋𡈽𡌛𡑮𡢽";
//文字列の長さを取得
StringInfo si = new StringInfo(str);
Console.WriteLine("文字列 = " + si.LengthInTextElements + "文字");
出力結果:
str = 5文字
詳細
文字列1「あいうえお」
文字列2「𠀋𡈽𡌛𡑮𡢽」
文字列1も文字列2も、どちらも5文字です。
しかし、文字列の長さを Length
を使用して取得すると、異なる結果が出ます。
//通常の文字列
string str1 = "あいうえお";
//サロゲートペアで構成された文字列
string str2 = "𠀋𡈽𡌛𡑮𡢽";
//文字列の長さを取得
Console.WriteLine("str1 = " + str1.Length + "文字");
Console.WriteLine("str2 = " + str2.Length + "文字");
出力結果:
str1 = 5文字
str2 = 10文字
str2はどう見ても5文字なのに、10文字とカウントされてしまいました。
これはサロゲートペア文字が4バイトで構成されている文字だからです。
Lengthを使って文字数をカウントすると「4バイト=2文字だよね?」という勘違いが起き、本来の2倍の長さの文字数が返ってきてしまいます。
・あ = 2バイト
・𠀋 = 4バイト
ではどうすれば良いかというと、 StringInfo.LengthInTextElements
プロパティを使用します。
//通常の文字列
string str1 = "あいうえお";
//サロゲートペアで構成された文字列
string str2 = "𠀋𡈽𡌛𡑮𡢽";
//文字列の長さを取得
StringInfo si = new StringInfo(str2);
Console.WriteLine("文字列1 = " + str1.Length + "文字");
Console.WriteLine("文字列2 = " + si.LengthInTextElements + "文字");
※ StringInfo.LengthInTextElements
プロパティを使用するために、 using System.Globalization
を追加しています。
出力結果:
str1 = 5文字
str2 = 5文字
正しい文字数が出力されました。
【参考】
Discussion