文字列 (C# プログラミング ガイド)
文字列は、値がテキストである String 型のオブジェクトです。内部では、テキストは Char オブジェクトの順次読み取り専用コレクションとして格納されます。C# の文字列の末尾には null 終端文字はありません。したがって、C# の文字列には任意の数の null 文字 ('\0') を埋め込むことができます。文字列の Length プロパティは、Unicode 文字の数ではなく、文字列に含まれている Char オブジェクトの数を表します。文字列内の個別の Unicode コード ポイントにアクセスするには、StringInfo オブジェクトを使用します。
文字列と System.String
C# では、string キーワードは String のエイリアスです。したがって、String と string は等価であり、どちらの名前付け規則を使用してもかまいません。String クラスは、文字列を安全に作成、操作、および比較するためのさまざまなメソッドを提供します。また、C# 言語は、一般的な文字列操作を簡略化するためにいくつかの演算子をオーバーロードします。キーワードの詳細については、「string (C# リファレンス)」を参照してください。型およびメソッドの詳細については、「String」を参照してください。
文字列の宣言と初期化
次の例に示すように、文字列はさまざまな方法で宣言および初期化できます。
// Declare without initializing.
string message1;
// Initialize to null.
string message2 = null;
// Initialize as an empty string.
// Use the Empty constant instead of the literal "".
string message3 = System.String.Empty;
//Initialize with a regular string literal.
string oldPath = "c:\\Program Files\\Microsoft Visual Studio 8.0";
// Initialize with a verbatim string literal.
string newPath = @"c:\Program Files\Microsoft Visual Studio 9.0";
// Use System.String if you prefer.
System.String greeting = "Hello World!";
// In local variables (i.e. within a method body)
// you can use implicit typing.
var temp = "I'm still a strongly-typed System.String!";
// Use a const string to prevent 'message4' from
// being used to store another string value.
const string message4 = "You can't get rid of me!";
// Use the String constructor only when creating
// a string from a char*, char[], or sbyte*. See
// System.String documentation for details.
char[] letters = { 'A', 'B', 'C' };
string alphabet = new string(letters);
文字列を文字の配列で初期化する場合を除き、文字列オブジェクトの作成に new 演算子を使用しないでください。
文字列の長さが 0 の新しい String オブジェクトを作成するには、Empty 定数値で文字列を初期化します。長さ 0 の文字列のリテラル文字列表現は "" です。null ではなく Empty 値で文字列を初期化することで、NullReferenceException が発生する可能性が低くなります。アクセス前に文字列の値を確認するには、静的な IsNullOrEmpty(String) メソッドを使用します。
文字列オブジェクトの不変性
文字列オブジェクトは変更不可です。つまり、作成した文字列オブジェクトは変更できません。文字列を変更するように見える String メソッドと C# 演算子はすべて、実際には新しい文字列オブジェクトで結果を返します。次の例では、s1 と s2 の内容を連結して 1 つの文字列を形成するときに、2 つの元の文字列は変更されません。+= 演算子で、連結した内容を含む新しい文字列が作成されます。新しいオブジェクトは変数 s1 に代入され、s1 に代入された元のオブジェクトはガベージ コレクションに対して解放されます。これは、他の変数がこのオブジェクトへの参照を保持していないためです。
string s1 = "A string is more ";
string s2 = "than the sum of its chars.";
// Concatenate s1 and s2. This actually creates a new
// string object and stores it in s1, releasing the
// reference to the original object.
s1 += s2;
System.Console.WriteLine(s1);
// Output: A string is more than the sum of its chars.
文字列の "変更" では、実際には文字列が新しく作成されるため、文字列への参照を作成するときには注意が必要です。文字列の参照を作成し、基の文字列を "変更" する場合、参照は文字列が変更されたときに作成された新しいオブジェクトではなく、元のオブジェクトを指したままになります。この動作を表すコードの例を次に示します。
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
元の文字列での検索操作や置換操作などの変更に基づく新しい文字列を作成する方法の詳細については、「方法 : 文字列の内容を変更する (C# プログラミング ガイド)」を参照してください。
標準リテラル文字列と逐語的リテラル文字列
次の例に示すように、C# で提供されるエスケープ文字を埋め込む必要がある場合は、標準リテラル文字列を使用します。
string columns = "Column 1\tColumn 2\tColumn 3";
//Output: Column 1 Column 2 Column 3
string rows = "Row 1\r\nRow 2\r\nRow 3";
/* Output:
Row 1
Row 2
Row 3
*/
string title = "\"The \u00C6olean Harp\", by Samuel Taylor Coleridge";
//Output: "The Æolean Harp", by Samuel Taylor Coleridge
文字列テキストに円記号が含まれる場合 (ファイル パスなど) は、使いやすさと読みやすさを考慮して、逐語的文字列を使用します。逐語的文字列は、文字列テキストの一部として改行文字を保持するため、複数行文字列の初期化に使用できます。引用符を逐語的文字列に埋め込むには、二重の引用符を使用します。逐語的文字列の一般的な使用方法の例を次に示します。
string filePath = @"C:\Users\scoleridge\Documents\";
//Output: C:\Users\scoleridge\Documents\
string text = @"My pensive SARA ! thy soft cheek reclined
Thus on mine arm, most soothing sweet it is
To sit beside our Cot,...";
/* Output:
My pensive SARA ! thy soft cheek reclined
Thus on mine arm, most soothing sweet it is
To sit beside our Cot,...
*/
string quote = @"Her name was ""Sara.""";
//Output: Her name was "Sara."
文字列のエスケープ シーケンス
エスケープ シーケンス |
文字名 |
Unicode エンコーディング |
---|---|---|
\' |
単一引用符 |
0x0027 |
\" |
二重引用符 |
0x0022 |
\\ |
円記号 |
0x005C |
\0 |
Null |
0x0000 |
\a |
警告 |
0x0007 |
\b |
バックスペース |
0x0008 |
\f |
フォーム フィード |
0x000C |
\n |
改行 |
0x000A |
\r |
キャリッジ リターン |
0x000D |
\t |
水平タブ。 |
0x0009 |
\U |
サロゲート ペアの Unicode エスケープ シーケンス |
\Unnnnnnnn |
\u |
Unicode エスケープ シーケンス |
\u0041 = "A" |
\v |
垂直タブ |
0x000B |
\x |
Unicode エスケープ シーケンス (可変長である点を除き "\u" に類似) |
\x0041 = "A" |
[!メモ]
コンパイル時に、逐語的文字列はエスケープ シーケンスと同様に通常の文字列に変換されます。したがって、逐語的文字列をデバッガーのウォッチ ウィンドウで表示すると、ソース コードの逐語的バージョンではなく、コンパイラが追加したエスケープ文字が表示されます。たとえば、逐語的文字列 @"C:\files.txt" は、ウォッチ ウィンドウでは "C:\\files.txt" と表示されます。
書式指定文字列
書式指定文字列は、内容が実行時に動的に決定される文字列です。静的な Format メソッドを使用して、実行時に他の値に置換されるプレースホルダーを中かっこ内に埋め込むことで、書式指定文字列を作成します。書式指定文字列を使用して、ループの各反復処理の結果を出力する例を次に示します。
class FormatString
{
static void Main()
{
// Get user input.
System.Console.WriteLine("Enter a number");
string input = System.Console.ReadLine();
// Convert the input string to an int.
int j;
System.Int32.TryParse(input, out j);
// Write a different string each iteration.
string s;
for (int i = 0; i < 10; i++)
{
// A simple format string with no alignment formatting.
s = System.String.Format("{0} times {1} = {2}", i, j, (i * j));
System.Console.WriteLine(s);
}
//Keep the console window open in debug mode.
System.Console.ReadKey();
}
}
WriteLine メソッドのオーバーロードは、パラメーターとして書式指定文字列を受け取ります。したがって、メソッドを明示的に呼び出さずに書式指定リテラル文字列を埋め込むことができます。ただし、WriteLine メソッドを使用して Visual Studio の [出力] ウィンドウにデバッグ出力を表示する場合は、Format メソッドを明示的に呼び出す必要があります。これは、WriteLine は、書式指定文字列ではなく文字列のみを受け入れるためです。書式指定文字列の詳細については、「型の書式設定」を参照してください。
部分文字列
部分文字列は、1 つの文字列に含まれる一連の文字です。元の文字列の一部から新しい文字列を作成するには、Substring メソッドを使用します。IndexOf メソッドを使用して、1 つまたは複数の部分文字列を検索できます。指定されたすべての部分文字列を新しい文字列に置換するには、Replace メソッドを使用します。Substring メソッドと同様に、Replace は実際には新しい文字列を返し、元の文字列は変更しません。詳細については、「方法 : String のメソッドを使用して文字列を検索する (C# プログラミング ガイド)」および「方法 : 文字列の内容を変更する (C# プログラミング ガイド)」を参照してください。
string s3 = "Visual C# Express";
System.Console.WriteLine(s3.Substring(7, 2));
// Output: "C#"
System.Console.WriteLine(s3.Replace("C#", "Basic"));
// Output: "Visual Basic Express"
// Index values are zero-based
int index = s3.IndexOf("C");
// index = 7
各文字へのアクセス
次の例に示すように、配列表記とインデックス値を使用すると、それぞれの文字への読み取り専用アクセスが可能になります。
string s5 = "Printing backwards";
for (int i = 0; i < s5.Length; i++)
{
System.Console.Write(s5[s5.Length - i - 1]);
}
// Output: "sdrawkcab gnitnirP"
String メソッドが、文字列内の個別の文字を変更する必要がある機能を提供していない場合は、StringBuilder オブジェクトを使用して個別の文字の "埋め込み先" を変更し、StringBuilder メソッドを使用することで、結果を格納する新しい文字列を作成できます。次の例では、特定の方法で元の文字列を変更し、将来使用するためにその結果を保存する必要があるとします。
string question = "hOW DOES mICROSOFT wORD DEAL WITH THE cAPS lOCK KEY?";
System.Text.StringBuilder sb = new System.Text.StringBuilder(question);
for (int j = 0; j < sb.Length; j++)
{
if (System.Char.IsLower(sb[j]) == true)
sb[j] = System.Char.ToUpper(sb[j]);
else if (System.Char.IsUpper(sb[j]) == true)
sb[j] = System.Char.ToLower(sb[j]);
}
// Store the new string.
string corrected = sb.ToString();
System.Console.WriteLine(corrected);
// Output: How does Microsoft Word deal with the Caps Lock key?
null 文字列と空の文字列
空の文字列は、文字数ゼロの System.String オブジェクトのインスタンスです。空の文字列は、空のテキスト フィールドを表すため、さまざまなプログラミング シナリオでよく使用されます。空の文字列は有効な System.String オブジェクトなので、メソッドを呼び出すことができます。空の文字列は、次のように初期化されます。
string s = String.Empty;
一方、null 文字列は System.String オブジェクトのインスタンスを参照しないので、null 文字列でメソッドを呼び出そうとすると NullReferenceException が発生します。しかし、null 文字列を他の文字列に連結したり、他の文字列と比較することは可能です。次に、null 文字列の参照によって例外がスローされる場合とされない場合の例を示します。
static void Main()
{
string str = "hello";
string nullStr = null;
string emptyStr = String.Empty;
string tempStr = str + nullStr;
// Output of the following line: hello
Console.WriteLine(tempStr);
bool b = (emptyStr == nullStr);
// Output of the following line: False
Console.WriteLine(b);
// The following line creates a new empty string.
string newStr = emptyStr + nullStr;
// Null strings and empty strings behave differently. The following
// two lines display 0.
Console.WriteLine(emptyStr.Length);
Console.WriteLine(newStr.Length);
// The following line raises a NullReferenceException.
//Console.WriteLine(nullStr.Length);
// The null character can be displayed and counted, like other chars.
string s1 = "\x0" + "abc";
string s2 = "abc" + "\x0";
// Output of the following line: * abc*
Console.WriteLine("*" + s1 + "*");
// Output of the following line: *abc *
Console.WriteLine("*" + s2 + "*");
// Output of the following line: 4
Console.WriteLine(s2.Length);
}
文字列を迅速に作成するための StringBuilder の使用
.NET での文字列操作は高度に最適化されており、ほとんどの場合パフォーマンスに大きく影響することはありません。ただし、短いループが数百回または数千回実行されている場合など、シナリオによっては文字列操作がパフォーマンスに影響する可能性があります。StringBuilder クラスが作成する文字列バッファーにより、プログラムで大量の文字列操作を実行する場合のパフォーマンスが向上します。StringBuilder 文字列を使用すると、組み込み文字列データ型ではサポートされていない個別の文字を再割り当てできます。たとえば、このコードでは、新しい文字列を作成せずに、文字列の内容を変更します。
System.Text.StringBuilder sb = new System.Text.StringBuilder("Rat: the ideal pet");
sb[0] = 'C';
System.Console.WriteLine(sb.ToString());
System.Console.ReadLine();
//Outputs Cat: the ideal pet
この例では、StringBuilder オブジェクトを使用して、複数の数値型から 1 つの文字列を作成します。
class TestStringBuilder
{
static void Main()
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
// Create a string composed of numbers 0 - 9
for (int i = 0; i < 10; i++)
{
sb.Append(i.ToString());
}
System.Console.WriteLine(sb); // displays 0123456789
// Copy one character of the string (not possible with a System.String)
sb[0] = sb[9];
System.Console.WriteLine(sb); // displays 9123456789
}
}
文字列、拡張メソッド、および LINQ
String 型は IEnumerable<T> を実装するため、Enumerable クラスで定義されている拡張メソッドを文字列で使用できます。見やすさを考慮して、これらのメソッドは String 型の IntelliSense からは除外されていますが、使用できます。文字列で LINQ クエリ式を使用することもできます。詳細については、「LINQ と文字列」を参照してください。
関連トピック
トピック |
Description |
---|---|
文字列の内容を変更するコード例を紹介します。 |
|
+ 演算子と Stringbuilder クラスを使用して、コンパイル時および実行時に文字列を結合する方法について説明します。 |
|
文字列の序数比較を実行する方法を示します。 |
|
String.Split メソッドを使用して文字列を解析するコード例を紹介します。 |
|
特定のメソッドを使用して文字列を検索する方法について説明します。 |
|
正規表現を使用して文字列を検索する方法について説明します。 |
|
文字列を安全に解析して、有効な数値があるかどうかを確認する方法を示します。 |
|
"01/24/2008" などの文字列を System.DateTime オブジェクトに変換する方法を示します。 |
|
System.String メソッドおよび System.Text.StringBuilder メソッドを使用して基本的な文字列操作を実行するトピックへのリンクを示します。 |
|
文字列に文字または空白を挿入する方法について説明します。 |
|
文字列を比較する方法について説明し、C# および Visual Basic での例を示します。 |
|
StringBuilder クラスの動的な文字列オブジェクトを作成および変更する方法について説明します。 |
|
LINQ クエリを使用してさまざまな文字列操作を実行する方法について説明します。 |
|
C# のプログラミング要素について説明するトピックへのリンクを示します。 |