🧑‍🤝‍🧑

【C#】サロゲートペア文字のカウント方法

2024/08/03に公開

結論

サロゲートペア文字をカウントする際は、 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