雑記 |
Visual Basic 中学校 > 雑記 >
2024/1/5
String.Length などで正確に数えられるのは Unicode 第0面(BMP)に収録されている文字だけです。
.NETの文字数の取得機能のほとんどはString.Lengthに依存しています。
Unicode 第1面以降の文字や結合文字の見かけの文字数を数えたい場合は、Runeの数を数えたり、StringInfoクラスの機能を使用します。
日本や中国などを含めて日常的に使う文字はUnicode 第0面(BPM)に含まれています。通常Unicode第1面以降の文字や結合文字を使用することはありません。
🗿などの多くの絵文字はUnicode第1面に収録されており、最近は絵文字を使う人が増えているように感じます。このような絵文字を1文字と数えるにはString.Length以外の手段が必要です。
日本や中国ではごくまれに地名や人名などの固有名詞にUnicode第1面以降の文字が使われている場合があります。
また、日本の漢字は同じ漢字なのに点の位置など形が微妙に違うバリエーション(異字体)が非常に多いものがあり、そのような違いを結合文字を使って表現することが可能です。しかし、この使い方は2024年現在ではほとんど普及していません。
古代エジプトのヒエログリフのような古代文字や特殊な用途で使用される文字がUnicode第1面以降に収録されている場合があります。
みなさんが試せるように上の画像で使っている文字をここに掲載しておきます。
A1&あ각★☃ΩⒽ山竜你𩸽𓀉𫛣🗿🗻🗼
あ゙あ゚あ̰👩👨👦👧🏴☠⚔️
それぞれの方法で文字数を数えるコンソールアプリ(.NET 8)のサンプルを紹介します。
ご利用の環境によっては文字がうまく表示されないかもしれません。使っているフォントにその文字が収録されていなかったり、ソフトウェアがUnicodeに完全に対応していなかったりする場合があるからです。
C#
namespace CsConsole
{
internal class Program
{
static void Main(string[] args)
{
PrintLength("A");
PrintLength("あ");
PrintLength("☃");
PrintLength("山");
PrintLength("𩸽");
PrintLength("𓀉");
PrintLength("🗿");
PrintLength("あ゙");
PrintLength("👩👨👦👧");
PrintLength("⚔️");
}
private static void PrintLength(string text)
{
int len1 = text.Length; //String.Length
int len2 = text.EnumerateRunes().Count(); //Runeの数
int len3 = EnumerateTextElements(text).Count(); //TextElementの数
System.Diagnostics.Debug.WriteLine($"{text} Length:{len1} Runes:{len2} Text Elements:{len3}");
}
private static IEnumerable<string> EnumerateTextElements(string text)
{
var enumerator = System.Globalization.StringInfo.GetTextElementEnumerator(text);
while (enumerator.MoveNext())
{
yield return (string)enumerator.Current;
}
}
}
}
VB
Module Program
Sub Main(args As String())
PrintLength("A")
PrintLength("あ")
PrintLength("☃")
PrintLength("山")
PrintLength("𩸽")
PrintLength("𓀉")
PrintLength("🗿")
PrintLength("あ゙")
PrintLength("👩👨👦👧")
PrintLength("⚔️")
End Sub
Private Sub PrintLength(text As String)
Dim len1 As Integer = text.Length 'String.Length
Dim len2 As Integer = text.EnumerateRunes().Count() 'Runeの数
Dim len3 As Integer = EnumerateTextElements(text).Count() 'TextElementの数
Debug.WriteLine($"{text} Length:{len1} Runes:{len2} Text Elements:{len3}")
End Sub
Private Iterator Function EnumerateTextElements(text As String) As IEnumerable(Of String)
Dim enumerator = Globalization.StringInfo.GetTextElementEnumerator(text)
While enumerator.MoveNext()
Yield CStr(enumerator.Current)
End While
End Function
End Module
実行すると出力ウィンドウに次のように出力されます。
A Length:1 Runes:1 Text Elements:1 あ Length:1 Runes:1 Text Elements:1 ☃ Length:1 Runes:1 Text Elements:1 山 Length:1 Runes:1 Text Elements:1 𩸽 Length:2 Runes:1 Text Elements:1 𓀉 Length:2 Runes:1 Text Elements:1 🗿 Length:2 Runes:1 Text Elements:1 あ゙ Length:2 Runes:2 Text Elements:1 👩👨👦👧 Length:11 Runes:7 Text Elements:1 ⚔️ Length:2 Runes:2 Text Elements:1
例: char、Rune、テキスト要素のインスタンス数を数える
Unicodeの世界 ~絵文字の連結編~
https://qiita.com/noritsune/items/46134cb7a50236540be5