文字列内の指定した範囲を文字列として取得するには、String.Substringメソッドを使います。Substringメソッドを使えば、Stringの指定した位置から指定した文字数分のStringを取得することができます。
以下にSubstringメソッドを使用した具体例を幾つか紹介します。文字の位置はインデックスで指定しますが、先頭の文字のインデックスが 0 なので、n 文字目のインデックスは (n-1) になることに注意してください。
Dim s As String = "あいうえお" '先頭から2文字を取得する。先頭の文字のインデックスは0。 Dim s1 As String = s.Substring(0, 2) '「あい」となる '2文字目(インデックスは1)から3文字を取得する Dim s2 As String = s.Substring(1, 3) '「いうえ」となる '4文字目(インデックスは3)から最後まで取得する Dim s3 As String = s.Substring(3) '「えお」となる '文字列の長さより長い文字列を取得しようとしてみる 'Dim s4 As String = s.Substring(0, 100) '例外ArgumentOutOfRangeExceptionが発生 '文字列の長さより大きい開始位置を指定してみる 'Dim s5 As String = s.Substring(100) '例外ArgumentOutOfRangeExceptionが発生 '開始位置に負の数を指定してみる 'Dim s6 As String = s.Substring(-1) '例外ArgumentOutOfRangeExceptionが発生
string s = "あいうえお"; //先頭から2文字を取得する。先頭の文字のインデックスは0。 string s1 = s.Substring(0, 2); //「あい」となる //2文字目(インデックスは1)から3文字を取得する string s2 = s.Substring(1, 3); //「いうえ」となる //4文字目(インデックスは3)から最後まで取得する string s3 = s.Substring(3); //「えお」となる //文字列の長さより長い文字列を取得しようとしてみる //string s4 = s.Substring(0, 100); //例外ArgumentOutOfRangeExceptionが発生 //文字列の長さより大きい開始位置を指定してみる //string s5 = s.Substring(100); //例外ArgumentOutOfRangeExceptionが発生 //開始位置に負の数を指定してみる //string s6 = s.Substring(-1); //例外ArgumentOutOfRangeExceptionが発生
VB.NETでは、Mid関数を使ってSubstringメソッドと同じことができます。また、文字列の先頭から指定した長さの文字列を返すLeft関数と、文字列の末尾から指定された長さの文字列を返すRight関数もあります。これらの関数に関しては、「C#でMid、Left、Right関数の代わりになるものは?」をご覧ください。
Substringメソッドのパラメータに指定する開始位置や文字列の長さは、Stringオブジェクトに含まれているCharオブジェクト(StringオブジェクトのCharsプロパティが返すChar型配列)の位置と数になります。よって、2つ以上のCharオブジェクトで1つの文字を表すサロゲートペア(代用対)や結合文字列(Combining Character Sequence、組み合わせ文字シーケンス)が含まれている場合は、Unicode文字の位置と長さを指定しても思ったような結果を得られません。
補足:サロゲートペアや結合文字列については、「サロゲートペアや結合文字が含まれているか調べる」で簡単に説明しています。
サロゲートペアや結合文字列が含まれている場合でもUnicode文字数を指定して部分文字列を正しく取得するには、StringInfo.SubstringByTextElementsメソッド(System.Globalization名前空間)を使います。SubstringByTextElementsメソッドの使い方は、Substringメソッドと同じです。
'結合文字列を含む文字列 Dim s As String = "a" & ChrW(&H301) & "a" & ChrW(&H302) & "a" & _ ChrW(&H303) & "a" & ChrW(&H304) & "a" & ChrW(&H305) 'StringInfoオブジェクトを作成 Dim si As New System.Globalization.StringInfo(s) '先頭から2文字を取得する Dim s1 As String = si.SubstringByTextElements(0, 2) '2文字目から3文字を取得する Dim s2 As String = si.SubstringByTextElements(1, 3) '4文字目から最後まで取得する Dim s3 As String = si.SubstringByTextElements(3) '文字列の長さより長い文字列を取得しようとしてみる 'Dim s4 As String = si.SubstringByTextElements(0, 100) '例外ArgumentOutOfRangeExceptionが発生 '文字列の長さより大きい開始位置を指定してみる 'Dim s5 As String = si.SubstringByTextElements(100) '例外ArgumentOutOfRangeExceptionが発生 '開始位置に負の数を指定してみる 'Dim s6 As String = si.SubstringByTextElements(-1) '例外ArgumentOutOfRangeExceptionが発生
//結合文字列を含む文字列 string s = "a\u0301a\u0302a\u0303a\u0304a\u0305"; //StringInfoオブジェクトを作成 System.Globalization.StringInfo si = new System.Globalization.StringInfo(s); //先頭から2文字を取得する string s1 = si.SubstringByTextElements(0, 2); //2文字目から3文字を取得する string s2 = si.SubstringByTextElements(1, 3); //4文字目から最後まで取得する string s3 = si.SubstringByTextElements(3); //文字列の長さより長い文字列を取得しようとしてみる string s4 = si.SubstringByTextElements(0, 100); //例外ArgumentOutOfRangeExceptionが発生 //文字列の長さより大きい開始位置を指定してみる string s5 = si.SubstringByTextElements(100); //例外ArgumentOutOfRangeExceptionが発生 //開始位置に負の数を指定してみる string s6 = si.SubstringByTextElements(-1); //例外ArgumentOutOfRangeExceptionが発生
このコードの結果、s1、s2、s3に代入される文字列は、以下のようになります(画像で表示しています)。
ちなみに、SubstringByTextElementsメソッドの代わりにSubstringメソッドを使用すると、以下のような結果になります(画像で表示しています)。
SubstringByTextElementsメソッドは、.NET Framework 2.0以降でしか使用できません。以下に.NET Framework 1.1以前でも使えるStringInfo.SubstringByTextElementsメソッドの代わりになるであろうメソッドの例を示します。
''' <summary> ''' StringInfo.SubstringByTextElementsメソッドと同じことをする ''' </summary> ''' <param name="str">文字列</param> ''' <param name="startingTextElement">開始位置</param> ''' <param name="lengthInTextElements">長さ</param> ''' <returns>部分文字列</returns> Public Shared Function SubstringByTextElements(ByVal str As String, _ ByVal startingTextElement As Integer, _ ByVal lengthInTextElements As Integer) As String If startingTextElement < 0 Then Throw New ArgumentOutOfRangeException("startingTextElement", _ "正の数値が必要です。") End If If lengthInTextElements < 0 Then Throw New ArgumentOutOfRangeException("lengthInTextElements", _ "正の数値が必要です。") End If 'サロゲートペアや結合文字列を考慮したインデックスを取得する Dim indexes As Integer() = _ System.Globalization.StringInfo.ParseCombiningCharacters(str) If str.Length = 0 OrElse indexes.Length <= startingTextElement Then Throw New ArgumentOutOfRangeException("startingTextElement", _ "指定された引数は、有効な値の範囲内にありません。") End If If indexes.Length - lengthInTextElements < startingTextElement Then Throw New ArgumentOutOfRangeException("lengthInTextElements", _ "指定された引数は、有効な値の範囲内にありません。") End If 'Substringに指定する開始位置を取得する Dim start As Integer = indexes(startingTextElement) '最後まで取得するか If startingTextElement + lengthInTextElements = indexes.Length Then Return str.Substring(start) End If 'Substringで部分文字列を取得する Return str.Substring(start, _ indexes(lengthInTextElements + startingTextElement) - start) End Function
/// <summary> /// StringInfo.SubstringByTextElementsメソッドと同じことをする /// </summary> /// <param name="str">文字列</param> /// <param name="startingTextElement">開始位置</param> /// <param name="lengthInTextElements">長さ</param> /// <returns>部分文字列</returns> public static string SubstringByTextElements(string str, int startingTextElement, int lengthInTextElements) { if (startingTextElement < 0) { throw new ArgumentOutOfRangeException("startingTextElement", "正の数値が必要です。"); } if (lengthInTextElements < 0) { throw new ArgumentOutOfRangeException("lengthInTextElements", "正の数値が必要です。"); } //サロゲートペアや結合文字列を考慮したインデックスを取得する int[] indexes = System.Globalization.StringInfo.ParseCombiningCharacters(str); if (str.Length == 0 || indexes.Length <= startingTextElement) { throw new ArgumentOutOfRangeException("startingTextElement", "指定された引数は、有効な値の範囲内にありません。"); } if (indexes.Length - lengthInTextElements < startingTextElement) { throw new ArgumentOutOfRangeException("lengthInTextElements", "指定された引数は、有効な値の範囲内にありません。"); } //Substringに指定する開始位置を取得する int start = indexes[startingTextElement]; //最後まで取得するか if (startingTextElement + lengthInTextElements == indexes.Length) { return str.Substring(start); } //Substringで部分文字列を取得する return str.Substring(start, indexes[lengthInTextElements + startingTextElement] - start); }
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。