文字列操作のいろいろ 

基本用法

C#言語での文字列

C#言語での文字列は、文字型の配列ではなく、文字列型のオブジェクトです。
つまり、System.Char構造体の配列ではなく、System.Stringクラスのオブジェクトです。

Stringとstring

Stringstringは同じ意味です。前者が.NETの型を表すのに対し後者はC#型のキーワード(エイリアス)です。

文字列操作

文字列操作は頻出の重要な処理です。
ほとんどのことは既に用意されている機能で賄えます。
下記のメソッドはいずれも多くのオーバーロードが定義されています。

生成

stringは参照型なのですが、new演算子無しで直接リテラルを設定することが出来ます。
勿論new演算子で生成することもでき、いろんなコンストラクタが定義されています。

            // 直接文字列を指定 
            string s1 = "いろはにほへと";

            // コンストラクタに文字の配列を指定
            char[] array = { 'い','ろ','は','に','ほ' };
            string s2 = new string(array);  // いろはにほへと

            // 文字配列の2番目から三文字分
            string s3 = new string(array, 2, 3);  // はにほ

            // 指定文字の繰り返し
            string s4 = new string('い', 3); // いいい

配列とインデクサ

文字列中の各文字へは添え字でアクセスできます。
配列のように扱えますが、インデクサという文法によるものです。
配列への変換メソッドは用意されていますが、リストへの変換はLinqが必要です。

            string s1 = "いろはにほへと";

            // インデクサ
            char c1 = s1[3];    // に

            // 文字型配列へ変換
            char[] array = s1.ToCharArray();

            // 文字型のリストへ変換(uing System.Linq;が必要)
            List<char> list = s1.ToList();

等価比較

文字列同士の比較は==演算子で行えます。
Equalsメソッドも同じように扱えます。
String.Compareでも比較ができますがその方法が異なります。

            string s1 = "abcdefg";
            string s2 = "abcdefg";
            string s3 = "hijklmn";
            string s4 = "ABCDEFG";

            bool ret1 = s1 == s2;   // true
            bool ret2 = s1 == s3;   // false
            bool ret3 = s1 == s4;   // false

            bool ret4 = s1.Equals(s2);   // true
            bool ret5 = s1.Equals(s3);   // false
            bool ret6 = s1.Equals(s4);   // false

            int ret7 = String.Compare(s1, s2); // 0
            int ret8 = String.Compare(s1, s3); // -1
            int ret9 = String.Compare(s1, s4); // -1
            // 大文字小文字の区別なし
            int ret0 = String.Compare(s1, s4, true); // 0

置換

           string s1 = "いろはにほへと ちりぬるを わかよたれそ つねならむ";

           string ret1 = s1.Replace("ちりぬるを", "散りぬるを"); // いろはにほへと 散りぬるを わかよたれそ つねならむ

           // 挿入
           string ret2 = s1.Insert(10, "aaaa"); // いろはにほへと ちりaaaaぬるを わかよたれそ つねならむ

分割

            string s1 = "いろはにほへと ちりぬるを わかよたれそ つねならむ";

            string[] ret1 = s1.Split(" "); // 空白で分割された4つの文字列になります

抜き出し

            string ret3 = s1.Substring(8, 13); // ちりぬるを わかよたれそ

削除

            // 8文字目から13文字分を削除
            string ret2 = s1.Remove(8,13);  // いろはにほへと つねならむ

空白削除

            string s2 = " abc def ghi ";

            string ret4 = s2.Trim();        // "abc def ghi"
            string ret5 = s2.TrimStart();   // "abc def ghi "
            string ret6 = s2.TrimEnd();     // " abc def ghi"

結合


            string[] array = { "いろはにほへと", "ちりぬるを", "わかよたれそ", "つねならむ" };

            // いづれも実行結果は "いろはにほへと ちりぬるを わかよたれそ つねならむ"
            string s1 = string.Join(" ", array); 
            string s2 = string.Concat(array[0], " ", array[1], " ", array[2], " ", array[3]);
            string s3 = string.Format("{0} {1} {2} {3}", array[0], array[1], array[2], array[3]);
            string s4 = $"{array[0]} {array[1]} {array[2]} {array[3]}";
C#6.0から文字列補間(先頭に$を付けて{}の間に変数を設定できる文法)が追加されました。

精査

            string s1 = "いろはにほへと ちりぬるを わかよたれそ つねならむ";

            // 含まれるか
            bool ret1 = s1.Contains("ちりぬるを");    // true
            bool ret2 = s1.Contains("うゐのおくやま"); // false

            // 最初に見つかったインデックス
            int ret3 = s1.IndexOf(" ");  // 7
            int ret4 = s1.IndexOf("あ"); // -1

            // 最後に見つかったインデックス
            int ret5 = s1.LastIndexOf(" "); // 20
            int ret6 = s1.LastIndexOf("あ"); // -1

            // どれかが最初/最後に見つかったインデックス
            int ret7 = s1.IndexOfAny(new char[] { 'ち','わ'});    // 8
            int ret8 = s1.LastIndexOfAny(new char[] { 'ち', 'わ' }); // 14
            int ret9 = s1.IndexOfAny(new char[] { 'う', 'け' }); // -1

NULLと空文字列と空白

NULL・空文字列・空白の文字列はそれぞれ全く異なるものです。
            string s1 = null;
            string s2 = string.Empty;
            string s3 = " "; // 半角スペース
            string s4 = " "; // 全角スペース

            bool ret1 = string.Empty == ""; // true

            bool ret2 = string.IsNullOrEmpty(s1);   // true
            bool ret3 = string.IsNullOrEmpty(s2);   // true
            bool ret4 = string.IsNullOrEmpty(s3);   // false
            bool ret5 = string.IsNullOrEmpty(s4);   // false

            bool ret6 = string.IsNullOrWhiteSpace(s1);   // true
            bool ret7 = string.IsNullOrWhiteSpace(s2);   // true
            bool ret8 = string.IsNullOrWhiteSpace(s3);   // true
            bool ret9 = string.IsNullOrWhiteSpace(s4);   // true

変換

            // 大文字小文字変換
            string ret1 = "ABCDE".ToLower(); // abcde
            string ret2 = "abcde".ToUpper(); // ABCDE

            // 文字列に変換
            string ret3 = new SampleClass().ToString(); // クラス(参照型)
            string ret4 = new SampleStruct().ToString(); // 構造体(値型)

            // 数値に変換
            int ret5 = int.Parse("123"); // 123

            // 数値を変換
            string ret6 = 123.ToString(); // "123"
            string ret7 = "12".PadLeft(4); // "  12"
            string ret8 = "12".PadLeft(4, 'A'); //"AA12"

            // 文字列をバイト配列に変換
            System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

            string s1 = "いろはにほへと";
            byte[] array = System.Text.Encoding.GetEncoding("shift_JIS").GetBytes(s1);

            // バイト配列を文字列に変換
            string ret9 = System.Text.Encoding.GetEncoding("shift_JIS").GetString(array);
.NET Core以降でSJISを使うにはEncoding.RegisterProviderの処理が必要になりました。

文字列の長さとバイト長

            string s1 = "abcd";

            string s2 = "いろはにほへと";

            string s3 = "𠮟"; // サロゲ

            System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

            int ret1 = s1.Length; // 4
            int ret2 = s2.Length; // 7
            int ret3 = s3.Length; // 2

            int ret4 = System.Text.Encoding.GetEncoding("shift_JIS").GetByteCount(s1); // 4
            int ret5 = System.Text.Encoding.GetEncoding("shift_JIS").GetByteCount(s2); // 7
            int ret6 = System.Text.Encoding.GetEncoding("shift_JIS").GetByteCount(s3); // 2

改行コード

 string ret1 = Environment.NewLine;

逐語的識別子

ダブルクォーテーションに囲まれた文字列内で\(バックスラッシュ)はエスケープシーケンスを表しますが、先頭に@を付与するとそのまま文字列として解釈されます。
また、予約語に@を付与すると変数名としても使えます。

            //string s1 = "c:\code\Sample";
            string s2 = @"c:\code\Sample";

            string @string = "test";

その他

インターンプーリング

C#では、一度使われた文字列は特殊なディクショナリにプールされ、同じ文字列は生成されず再利用されます。
String.Intern(String) メソッド (System)
指定した String へのシステム参照を取得します。

正規表現

.NETの正規表現は他の代表的な言語とほぼ一緒です。
.NET の正規表現 - .NET
正規表現を使用して、特定の文字パターンの検索、テキストの検証、テキスト部分文字列の処理、抽出した文字列の .NET のコレクションへの追加を行います。

StringBuilderクラス

文字列操作に特化したクラスもあります。 連結・削除・置換・削除などを高速軽量に行えます。
StringBuilder クラス (System.Text)
可変型の文字列を表します。 このクラスは継承できません。

Linqと文字列

文字列自体のフィルタリングや並べ替えも出来ますし、文字列を配列(コレクション)にすればその操作も勿論可能です。
C# の統合言語クエリ (LINQ)
C# の統合言語クエリ (LINQ) について説明します。
基本用法
スポンサーリンク
C#プログラミング再入門