ここではStringクラスに用意されている文字列加工・編集の操作を行うためのメソッドについて見ていきます。

なお、この文章ではUnicode正規形や正規化、サロゲートペアを含む文字列の扱いについては踏み込みません。 必要に応じて他のドキュメントを参照してください。

§1 文字列の加工・編集

ここで解説する文字列の加工・編集の操作と、対応するStringクラスのメソッドを表にまとめます。 個々のメソッドの詳細については順に解説していきます。

文字列操作と対応するStringクラスのメソッド
文字列操作 対応するStringクラスのメソッド 解説へのリンク
文字列同士の連結 Concat、+演算子、+=演算子 解説へ
文字列の複製 Copy 解説へ
文字列からの一部分の取得
(部分文字列の切り出し)
Substring 解説へ
文字列への挿入 Insert 解説へ
文字列の一部分の削除 Remove 解説へ
文字列の一部分の置換 Replace 解説へ
単一文字列から文字列配列への分割
(任意の区切り文字での分割)
Split 解説へ
文字列配列から単一文字列への結合
(任意の区切り文字での結合)
Join 解説へ
文字列前後の余白の削除 Trim, TrimEnd, TrimStart 解説へ
文字列前後への余白の挿入 PadLeft, PadRight 解説へ
文字列の大文字化・小文字化 ToUpper, ToLower, ToUpperInvariant, ToLowerInvariant 解説へ
書式化
(数値などの値の文字列化)
Format 解説へ
単一文字列からChar配列への変換 ToCharArray, CopyTo 解説へ
Char配列から単一文字列への変換 Stringコンストラクタ 解説へ
文字列操作 対応するStringクラスのメソッド 解説へのリンク

なお、文字列の探索と比較については文字列の探索・比較で解説します。 また、Stringクラスのメソッドではワイルドカードのようなパターンマッチングを使った文字列の加工・編集は出来ないので、そういった場合は正規表現(Regexクラス)を使います。

§1.1 連結 (Concat, +, +=)

String.Concatメソッドは文字列同士の連結を行う静的メソッドで、任意の数の文字列を連結出来ます。 またC#、VBでは加算演算子+、および複合代入の加算演算子+=を使った連結もできるようになっています。

using System;

class Sample {
  static void Main()
  {
    string s1 = "foo";
    string s2 = "bar";

    Console.WriteLine(s1 + s2);
    Console.WriteLine(s1 + s2 + "baz");
    Console.WriteLine(s1 + s2 + "baz" + "qux");

    Console.WriteLine(String.Concat(s1, s2));
    Console.WriteLine(String.Concat(s1, s2, "baz"));
    Console.WriteLine(String.Concat(s1, s2, "baz", "qux"));

    s1 = s1 + "baz";

    Console.WriteLine(s1);

    s2 += "quz";

    Console.WriteLine(s2);
  }
}
実行結果
foobar
foobarbaz
foobarbazqux
foobar
foobarbaz
foobarbazqux
foobaz
barqux

.NET Framework 4からは、IEnumerable<String>を引数にとるバージョンのConcatも用意されています。 これを利用するとListに格納されている複数の文字列を一つに連結するということがメソッド呼び出し一つで行えます。

using System;
using System.Collections.Generic;

class Sample {
  static void Main()
  {
    List<string> l = new List<string>() {"foo", "bar", "baz", "qux"};

    Console.WriteLine(String.Concat(l));
  }
}
実行結果
foobarbazqux

§1.2 複製 (Copy)

String.Copyメソッドは文字列の複製を行う静的メソッドです。 見かけ上の動作は文字列変数の単なる代入と似ていますが、Copyメソッドでは指定された文字列と同じ内容の新しいインスタンスが作成される点が異なります。

using System;

class Sample {
  static void Main()
  {
    string s1 = "foo";
    string s2;
    string s3;

    s2 = s1;
    s3 = String.Copy(s1);

    Console.WriteLine(s1);
    Console.WriteLine("{0} {1}", s2, Object.ReferenceEquals(s2, s1));
    Console.WriteLine("{0} {1}", s3, Object.ReferenceEquals(s3, s1));
  }
}
実行結果
foo
foo True
foo False

代入と複製の違い、参照の比較についてはオブジェクトの複製値型と参照型 §.同値性・同一性の比較などを参照してください。

§1.3 切り出し (Substring)

String.Substringメソッドは文字列から部分文字列を切り出すメソッドで、切り出す最初のインデックスと長さを指定することで文字列の一部分を取得します。 長さを指定しなかった場合は、指定されたインデックスから文字列の最後までが返されます。

using System;

class Sample {
  static void Main()
  {
    string s = "The quick brown fox jumps over the lazy dog";

    Console.WriteLine(s.Substring(0, 9)); // 0文字目から9文字分を切り出す
    Console.WriteLine(s.Substring(31)); // 31文字目以降を切り出す
  }
}
実行結果
The quick
the lazy dog

§1.4 挿入 (Insert)

String.Insertメソッドは文字列に別の文字列を挿入するメソッドです。 Insertメソッドは別の文字列を挿入した結果を返します。

using System;

class Sample {
  static void Main()
  {
    string s = "The quick brown fox jumps over the lazy dog";

    Console.WriteLine(s);
    Console.WriteLine(s.Insert(40, "white ")); // 40文字目に"white "を挿入
  }
}
実行結果
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy white dog

このメソッドでは、元の文字列には変更を加えず、挿入した結果を新しい文字列として返します。



§1.5 削除 (Remove)

String.Removeメソッドは文字列の一部分を削除した文字列を取得するメソッドで、削除を始める最初のインデックスと長さを指定することで文字列の一部分を削除します。 長さを指定しなかった場合は、指定されたインデックスから文字列の最後までが削除されます。

using System;

class Sample {
  static void Main()
  {
    string s = "The quick brown fox jumps over the lazy dog";

    Console.WriteLine(s);
    Console.WriteLine(s.Remove(4, 6)); // 4文字目から6文字分を削除
    Console.WriteLine(s.Remove(25)); // 25文字目以降を削除
  }
}
実行結果
The quick brown fox jumps over the lazy dog
The brown fox jumps over the lazy dog
The quick brown fox jumps

このメソッドでは、元の文字列には変更を加えず、削除した結果を新しい文字列として返します。

位置を指定した削除ではなく、部分文字列を指定した削除(特定の文字列の削除)にはReplaceメソッドを使用します。

§1.6 置換 (Replace)

String.Replaceメソッドは文字列内の部分文字列を別の部分文字列に置き換えるメソッドです。 一致する文字列はすべて置き換えられます。

using System;

class Sample {
  static void Main()
  {
    string s = "The quick brown fox jumps over the lazy dog";

    Console.WriteLine(s);
    Console.WriteLine(s.Replace("quick", "clever")); // "quick"を"clever"に置き換え
    Console.WriteLine(s.Replace("lazy", "silly")); // "lazy"を"silly"に置き換え
  }
}
実行結果
The quick brown fox jumps over the lazy dog
The clever brown fox jumps over the lazy dog
The quick brown fox jumps over the silly dog

このメソッドでは、元の文字列には変更を加えず、置換した結果を新しい文字列として返します。

置き換え後の文字列にnull/Nothingもしくは空文字(String.Empty)を指定すると、置き換え前の部分文字列を削除することが出来ます。

using System;

class Sample {
  static void Main()
  {
    string s = "The quick brown fox jumps over the lazy dog";

    Console.WriteLine(s);
    Console.WriteLine(s.Replace("brown ", "")); // "brown "を削除
    Console.WriteLine(s.Replace("lazy ", null)); // "lazy "を削除
  }
}
実行結果
The quick brown fox jumps over the lazy dog
The quick fox jumps over the lazy dog
The quick brown fox jumps over the dog

また、Replaceメソッドでは文字(Char)単位での置換も行えます。

using System;

class Sample {
  static void Main()
  {
    string s = "The quick brown fox jumps over the lazy dog";

    Console.WriteLine(s);
    Console.WriteLine(s.Replace('o', 'a')); // oをaに置換
  }
}
実行結果
The quick brown fox jumps over the lazy dog
The quick brawn fax jumps aver the lazy dag

§1.7 分割 (Split)

String.Splitメソッドは文字列の分割を行うメソッドで、指定した文字または文字列を区切りとして分割した結果を文字列の配列で返します。

using System;

class Sample {
  static void Main()
  {
    string s = "The quick brown fox jumps over the lazy dog";
    string[] words = s.Split(' '); // 文字列sを空白を区切りとして分割

    foreach (string word in words) {
      Console.WriteLine(word);
    }
  }
}
実行結果
The
quick
brown
fox
jumps
over
the
lazy
dog

分割時のオプションとして、分割を行った結果生じる空の要素をどう扱うかどうかをStringSplitOptionsで指定できます。 StringSplitOptions.RemoveEmptyEntriesを指定した場合は、空の要素は結果から取り除かれます。 StringSplitOptions.Noneはデフォルトの値で、空の要素もそのまま返されます。

using System;

class Sample {
  static void Main()
  {
    string s = "<>field1<><>field2<>field3";
    string[] fields;

    // 文字列"<>"を区切りとして分割、空の要素は削除する
    Console.WriteLine("StringSplitOptions.RemoveEmptyEntries");

    fields = s.Split(new string[] {"<>"}, StringSplitOptions.RemoveEmptyEntries);

    Console.WriteLine("(count = {0})", fields.Length);

    foreach (string field in fields) {
      Console.WriteLine(field);
    }

    // 文字列"<>"を区切りとして分割、空の要素は削除しない
    Console.WriteLine("StringSplitOptions.None");

    fields = s.Split(new string[] {"<>"}, StringSplitOptions.None);

    Console.WriteLine("(count = {0})", fields.Length);

    foreach (string field in fields) {
      Console.WriteLine(field);
    }
  }
}
実行結果
StringSplitOptions.RemoveEmptyEntries
(count = 3)
field1
field2
field3
StringSplitOptions.None
(count = 5)

field1

field2
field3

§1.8 結合 (Join)

String.Joinメソッドは配列の結合を行う静的メソッドで、結合時の区切り文字と配列を指定し、それらを結合した結果を返します。

using System;

class Sample {
  static void Main()
  {
    string[] words = new string[] {"The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"};

    Console.WriteLine(String.Join(" ", words)); // 区切り文字を" "として結合
    Console.WriteLine(String.Join("<>", words)); // 区切り文字を"<>"として結合
  }
}
実行結果
The quick brown fox jumps over the lazy dog
The<>quick<>brown<>fox<>jumps<>over<>the<>lazy<>dog

.NET Framework 4からは、IEnumerable<String>を引数にとるバージョンのJoinも用意されています。 これを利用するとListに格納されている複数の文字列を一つに結合するということがメソッド呼び出し一つで行えます。

using System;
using System.Collections.Generic;

class Sample {
  static void Main()
  {
    List<string> l = new List<string>() {"The", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"};

    Console.WriteLine(String.Join(", ", l));
  }
}
実行結果
The, quick, brown, fox, jumps, over, the, lazy, dog

§1.9 余白の削除 (Trim, TrimEnd, TrimStart)

String.Trimメソッドは文字列の先頭と末尾にある空白文字を削除するメソッドです。 String.TrimStartメソッドでは先頭のみ、String.TrimEndメソッドでは末尾のみにある空白文字を削除します。

using System;

class Sample {
  static void Main()
  {
    string s = "   The quick brown fox jumps over the lazy dog   ";

    Console.WriteLine("<{0}>", s);
    Console.WriteLine("<{0}>", s.Trim());
    Console.WriteLine("<{0}>", s.TrimStart());
    Console.WriteLine("<{0}>", s.TrimEnd());
  }
}
実行結果
<   The quick brown fox jumps over the lazy dog   >
<The quick brown fox jumps over the lazy dog>
<The quick brown fox jumps over the lazy dog   >
<   The quick brown fox jumps over the lazy dog>

このメソッドでは、半角および全角のスペースやタブだけでなく、改行文字なども空白文字として扱われます。 .NET Framework 4以降では、Unicodeで空白文字と定義されている文字(Char.IsWhiteSpacetrueとなる文字)が空白文字として扱われます。 それ以前のバージョンでの空白文字の扱いなど詳細は.NET Frameworkのドキュメントを参照してください。

また、削除する文字を明示的に指定することも出来ます。 この場合、スペース以外の文字も指定することが出来ます。

using System;

class Sample {
  static void Main()
  {
    string s = "123abc456def7890";
    char[] numbers = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

    Console.WriteLine(s);
    Console.WriteLine(s.Trim(numbers)); // 先頭と末尾の数字を削除
    Console.WriteLine(s.TrimStart(numbers)); // 先頭と数字を削除
    Console.WriteLine(s.TrimEnd(numbers)); // 末尾の数字を削除
  }
}
実行結果
123abc456def7890
abc456def
abc456def7890
123abc456def

§1.10 余白の挿入 (PadLeft, PadRight)

String.PadLeftメソッドは余白の挿入を行うメソッドで、指定された文字数になるように左側にスペースを挿入します。s String.PadRightメソッドはPadLeftメソッドとは逆に右側にスペースを挿入します。 指定された文字数より文字列の長さの方が大きい場合、スペースは挿入されません。 このメソッドを使うことで文字列を左寄せ・右寄せすることができます。

using System;

class Sample {
  static void Main()
  {
    string s = "foo";

    Console.WriteLine("<{0}>", s.PadLeft(6)); // 文字数が6になるように左側に余白を挿入
    Console.WriteLine("<{0}>", s.PadRight(6)); // 文字数が6になるように右側に余白を挿入
    Console.WriteLine("<{0}>", s.PadLeft(2)); // 文字数が2になるように左側に余白を挿入
    Console.WriteLine("<{0}>", s.PadRight(2)); // 文字数が2になるように右側に余白を挿入
  }
}
実行結果
<   foo>
<foo   >
<foo>
<foo>

スペース以外の文字を挿入するように指定することも出来ます。

using System;

class Sample {
  static void Main()
  {
    string s = "foo";

    Console.WriteLine("<{0}>", s.PadLeft(6, '*')); // 文字数が6になるように左側に'*'を挿入
    Console.WriteLine("<{0}>", s.PadRight(6, '-')); // 文字数が6になるように右側に'-'を挿入
  }
}
実行結果
<***foo>
<foo--->

中寄せ(センタリング)を行うように余白を挿入するメソッドは用意されていないので、そういった場合には独自に実装する必要があります。 実装例は§.センタリングを参照してください。

§1.11 大文字化・小文字化 (ToUpper, ToLower, ToUpperInvariant, ToLowerInvariant)

String.ToUpperメソッドは文字列を大文字化するメソッド、String.ToLowerメソッドは文字列を小文字化するメソッドです。

ToUpperメソッドとToLowerメソッドは現在のスレッドの(もしくは引数で指定された)カルチャの規則に基づいて大文字化・小文字化しますが、String.ToUpperInvariantメソッドString.ToLowerInvariantメソッドインバリアントカルチャ(特定の文化圏や言語に依存しない)の規則に基づいて大文字化・小文字化します。

using System;

class Sample {
  static void Main()
  {
    string s = "The Quick Brown Fox Jumps Over The Lazy Dog";

    Console.WriteLine(s);
    Console.WriteLine(s.ToUpper());
    Console.WriteLine(s.ToUpperInvariant());
    Console.WriteLine(s.ToLower());
    Console.WriteLine(s.ToLowerInvariant());
  }
}
実行結果
The Quick Brown Fox Jumps Over The Lazy Dog
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog

ToUpper/ToUpperInvariantToLower/ToLowerInvariantの違いは、大文字化・小文字化の際に参照される規則です。

例えば、トルコ語においては i の大文字は I(U+0049) ではなく İ(U+0131) で、I の小文字は i(U+0069) ではなく ı(U+0130) となるため、スレッドのカルチャがトルコ語の場合ToUpper/ToLowerの結果はToUpperInvariant/ToLowerInvariantと異なる結果となります。

using System;
using System.Globalization;
using System.Threading;

class Sample {
  static void Main()
  {
    Console.WriteLine(Thread.CurrentThread.CurrentCulture);
    Console.WriteLine("i: {0} {1}", "i".ToUpperInvariant(), "i".ToUpper());
    Console.WriteLine("I: {0} {1}", "I".ToLowerInvariant(), "I".ToLower());

    // 現在のスレッドのカルチャをtr-TR(トルコ語/トルコ)に変更
    Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("tr-TR");

    Console.WriteLine(Thread.CurrentThread.CurrentCulture);
    Console.WriteLine("i: {0} {1}", "i".ToUpperInvariant(), "i".ToUpper());
    Console.WriteLine("I: {0} {1}", "I".ToLowerInvariant(), "I".ToLower());
  }
}
実行結果
ja-JP
i: I I
I: i i
tr-TR
i: I İ
I: i ı

したがって、カルチャや変換規則を強く意識する必要がある場合はToUpper/ToLowerを用いる必要があります。 一方それ以外の多くの場合はToUpperInvariant/ToLowerInvariantで十分と言えます。

カルチャと変換規則についてはStringComparisonとStringComparerでも詳しく説明しています。

§1.12 書式化 (Format)

String.Formatメソッドは任意の引数を指定された書式に基づいて文字列化する静的メソッドです。

using System;

class Sample {
  static void Main()
  {
    DateTime dateTimeValue = new DateTime(2010, 9, 14, 1, 2, 3);
    string s = String.Format("{1:r}   {0:D}   {0:D4}   {0:N4}", 72, dateTimeValue);

    Console.WriteLine(s);
  }
}
実行結果
Tue, 14 Sep 2010 01:02:03 GMT   72   0072   72.0000

書式の詳細については書式指定子での解説を参照してください。

§1.13 Char配列への変換 (ToCharArray, CopyTo)

String.ToCharArrayメソッドは文字列をChar配列へ変換するメソッドです。

using System;

class Sample {
  static void Main()
  {
    string s = "The quick brown fox jumps over the lazy dog";
    char[] chars;

    chars = s.ToCharArray();

    for (int i = 0; i < chars.Length; i++) {
      Console.Write(chars[i]);
    }

    Console.WriteLine();

    // 配列を反転して表示
    Array.Reverse(chars);

    for (int i = 0; i < chars.Length; i++) {
      Console.Write(chars[i]);
    }

    Console.WriteLine();
  }
}
実行結果
The quick brown fox jumps over the lazy dog
god yzal eht revo spmuj xof nworb kciuq ehT

String.CopyToメソッドは、文字列の一部のみを別のChar配列にコピーするメソッドです。 ToCharArrayメソッドとは異なり、コピー先のChar配列をあらかじめ用意しておく必要があります。

using System;

class Sample {
  static void Main()
  {
    string s = "The quick brown fox jumps over the lazy dog";
    char[] chars = new char[11]; // コピー先となる配列

    s.CopyTo(4, chars, 0, 11); // 文字列の4文字目から11文字分を、コピー先配列のインデックス0を起点にコピー

    for (int i = 0; i < chars.Length; i++) {
      Console.Write("{0}/", chars[i]);
    }

    Console.WriteLine();
  }
}
実行結果
q/u/i/c/k/ /b/r/o/w/n/

§1.14 Char配列からの変換 (Stringコンストラクタ)

StringクラスのコンストラクタにChar配列を指定することにより、Char配列から文字列へ変換することが出来ます。

using System;

class Sample {
  static void Main()
  {
    char[] chars = new char[] {'b', 'a', 'r'};
    string s = new string(chars);

    Console.WriteLine(s);

    Array.Reverse(chars);

    Console.WriteLine(new string(chars));
  }
}
実行結果
bar
rab

また、マネージドコードのみの場合はほとんど使うことはありませんが、charのポインタやsbyteのポインタから文字列を作成することも出来ます。

using System;
using System.Text;

class Sample {
  static void Main()
  {
    byte[] data;
    string s;

    data = new byte[] {0x41, 0x42, 0x43};

    unsafe {
      fixed (byte* d = data) {
        s = new string((sbyte*)d, 0, 3);
      }
    }

    Console.WriteLine(s);

    data = new byte[] {0x93, 0xfa, 0x96, 0x7b, 0x8c, 0xea};

    unsafe {
      fixed (byte* d = data) {
        s = new string((sbyte*)d, 0, 6, Encoding.GetEncoding("shift_jis"));
      }
    }

    Console.WriteLine(s);
  }
}
実行結果
ABC
日本語

§2 Stringクラスで提供されない操作

ここではStringクラスで提供されない文字列操作と、それを実装する例を見ていきます。 以下の例では引数のチェック等は省略しています。

§2.1 部分文字列の計上 (Count)

Stringクラスでは文字列中に含まれる部分文字列の数(同じ文字列がいくつ含まれているか)を計上するメソッドは用意されていません。 以下は部分文字列の計上を行う例です。 Count1ではIndexOfメソッドを用いて部分文字列の探索を繰り返すことで数を計上しています。 Count2ではReplaceメソッドを用いて部分文字列を削除し、減った文字数をもとに計上しています。

部分文字列の計上
using System;

class Sample {
  static int Count1(string s, string substr)
  {
    for (int count = 0, lastIndex = 0;; count++) {
      int index = s.IndexOf(substr, lastIndex);

      if (index < 0) {
        return count;
      }
      else {
        lastIndex = index + substr.Length;
      }
    }
  }

  static int Count2(string s, string substr)
  {
    return (s.Length - s.Replace(substr, null).Length) / substr.Length;
  }

  static void Main()
  {
    string s = "かごめかごめ かごのなかのとりは いついつでやる";

    Console.WriteLine(s);
    Console.WriteLine(Count1(s, "かご"));
    Console.WriteLine(Count2(s, "かご"));
    Console.WriteLine(Count1(s, "いつ"));
    Console.WriteLine(Count2(s, "いつ"));
    Console.WriteLine(Count1(s, "か"));
    Console.WriteLine(Count2(s, "か"));
  }
}
実行結果
かごめかごめ かごのなかのとりは いついつでやる
3
3
2
2
4
4

§2.2 反転 (Reverse)

Stringクラスでは文字列の並びを反転するメソッドは用意されていません。 以下は文字列の反転を行う例です。 ToCharArrayメソッドを用いて一度Char配列にしてから、Array.Reverseメソッドにより反転したのちに再びStringに変換することで文字列の反転を実現しています。

文字列の反転
using System;

class Sample {
  static string Reverse(string s)
  {
    char[] chars = s.ToCharArray();

    Array.Reverse(chars);

    return new string(chars);
  }

  static void Main()
  {
    string s1 = "The quick brown fox jumps over the lazy dog";
    string s2 = "かごめかごめ かごのなかのとりは いついつでやる";

    Console.WriteLine(s1);
    Console.WriteLine(Reverse(s1));

    Console.WriteLine(s2);
    Console.WriteLine(Reverse(s2));
  }
}
実行結果
The quick brown fox jumps over the lazy dog
god yzal eht revo spmuj xof nworb kciuq ehT
かごめかごめ かごのなかのとりは いついつでやる
るやでついつい はりとのかなのごか めごかめごか

LINQを用いて次のように実装することもできます。

LINQを用いた文字列の反転
using System;
using System.Linq;

class Sample {
  static void Main()
  {
    string s = "かごめかごめ かごのなかのとりは いついつでやる";
    string r = new String(s.Reverse().ToArray());

    Console.WriteLine(s);
    Console.WriteLine(r);
  }
}
実行結果
かごめかごめ かごのなかのとりは いついつでやる
るやでついつい はりとのかなのごか めごかめごか

文字列にサロゲートペアが含まれている場合、上記の方法は正しく動作しません。

§2.3 範囲を指定した置換

Replaceメソッドでは、文字列の範囲を指定して別の文字列に置き換えることはできません。 そういった置換を行う場合は、Substringメソッドで文字列を切り出したあと置き換えたい文字列と連結するようにします。 次の例では、位置を指定して文字列の一部分を置き換えるReplaceメソッドを作成しています。

using System;

class Sample {
  // 文字列strのstart文字目からlength文字分をnewstrに置き換えるメソッド
  static string Replace(string str, int start, int length, string newstr)
  {
    return str.Substring(0, start) + newstr + str.Substring(start + length);
  }

  static void Main()
  {
    string s = "The quick brown fox jumps over the lazy dog";

    Console.WriteLine(s);
    Console.WriteLine(Replace(s, 4, 5, "clever")); // 4文字目から5文字分を"clever"に置き換え
  }
}
実行結果
The quick brown fox jumps over the lazy dog
The clever brown fox jumps over the lazy dog

§2.4 センタリング

StringクラスではPadLeftによる左詰め、PadRightによる右詰めは行えますが、文字列の中寄せ(センタリング)を行うメソッドは用意されていません。 以下は文字列のセンタリングを行う例です。 指定された幅で文字列が中央に来るよう左右に空白を入れています。 文字数よりも幅が下回る場合はそのままにします。

using System;

class Sample {
  static string Center(string s, int width)
  {
    int margin = (width - s.Length) / 2;

    if (margin <= 0) {
      return s;
    }
    else {
      string padding = new String(' ', margin);

      return String.Concat(padding, s, padding);
    }
  }

  static void Main()
  {
    string s = "foo";

    Console.WriteLine("<{0}>", Center(s, 5));
    Console.WriteLine("<{0}>", Center(s, 6));
    Console.WriteLine("<{0}>", Center(s, 10));
    Console.WriteLine("<{0}>", Center(s, 20));
    Console.WriteLine("<{0}>", Center(s, 0));
  }
}
実行結果
< foo >
< foo >
<   foo   >
<        foo        >
<foo>

§2.5 乗算演算子(*, *=)・繰り返した文字列の生成

Stringクラスでは乗算演算子はサポートされていません。 いくつかの言語では、乗算演算子を使って同じ文字の並びを任意の回数だけ繰り返した文字列を作ることが出来ますが、Stringクラスではそういった操作は用意されていません。 またString.Repeatのようなメソッドも用意されていません。 そのため、必要な回数だけ連結を繰り返すなどして作成する必要があります。

繰り返した文字列の作成
using System;

class Sample {
  static void Main()
  {
    // string s = "foo" * 10;
    string s = string.Empty;

    for (int i = 0; i < 10; i++) {
      s += "foo";
    }

    Console.WriteLine(s);
  }
}

この方法で長大な文字列を生成する場合は、パフォーマンスの観点からStringBuilderクラスを使うことも検討してください。


Stringクラスのコンストラクタを使うことで、同じ文字(1文字)を任意の回数だけ繰り替えした文字を作ることは出来ます。 この方法は1文字以上の文字列に対して用いることはできません。

同じ文字を繰り返した文字列の作成
using System;

class Sample {
  static void Main()
  {
    string s = new string('あ', 10); // 'あ'を10回くりかえした文字列を作る

    Console.WriteLine(s);
  }
}
実行結果
ああああああああああ

LINQのEnumerable.Repeatメソッドを用いれば、1文字以上の文字列を繰り返した文字列を作成することができます。

同じ文字列を繰り返した文字列の作成
using System;
using System.Linq;

class Sample {
  static void Main()
  {
    // "あいう"を10回くりかえした文字列を作る
    string s = string.Concat(Enumerable.Repeat("あいう", 10));

    Console.WriteLine(s);
  }
}
実行結果
あいうあいうあいうあいうあいうあいうあいうあいうあいうあいう

§3 VBの文字列操作関数

(このドキュメントは未整理です)

現在はあまり推奨されませんが、Microsoft.VisualBasic名前空間のStringsクラスのメソッドを使うことで、VB由来の文字列操作関数を使うことも出来ます。 VB.NETでもこれらの関数を使うことは出来ますが、新規に書くコードではできるだけStringクラスのメソッドを使うべきです。 これらの文字列操作関数ではインデックスが1から始まる(1-based)として扱われる一方、.NET Frameworkでは0から始まる(0-based)として扱われるため、混乱を招いたり意図しない動作となる可能性があります。

using System;
using Microsoft.VisualBasic;

class Sample {
  static void Main()
  {
    Console.WriteLine("<{0}>", Strings.LTrim("   foo"));
    Console.WriteLine("<{0}>", Strings.RTrim("foo   "));
    Console.WriteLine(Strings.UCase("foo"));
    Console.WriteLine(Strings.LCase("FOO"));
    Console.WriteLine(Strings.Mid("The quick brown fox jumps over the lazy dog", 1, 9)); // '1'文字目から9文字分を取得する
    Console.WriteLine("The quick brown fox jumps over the lazy dog".Substring(0, 9)); // '0'文字目から9文字分を取得する
    Console.WriteLine(Strings.InStr("The quick brown fox", "FOX", CompareMethod.Binary));
    Console.WriteLine(Strings.InStr("The quick brown fox", "FOX", CompareMethod.Text));
    Console.WriteLine("The quick brown fox".IndexOf("FOX"));
    Console.WriteLine("The quick brown fox".IndexOf("FOX", StringComparison.CurrentCultureIgnoreCase));
  }
}
実行結果
<foo>
<foo>
FOO
foo
The quick
The quick
0
17
-1
16