[C#] stringクラス(文字列)の使い方 – 基本的な文字列操作を解説

C#のstringクラスは、文字列を扱うための基本的なクラスです。

stringは不変(イミュータブル)で、一度作成された文字列は変更できません。

文字列の結合には+演算子やString.ConcatStringBuilderが使われます。

部分文字列を取得するにはSubstringメソッド、文字列の検索にはIndexOfContainsが使われます。

文字列の長さはLengthプロパティで取得でき、文字列の比較にはEqualsCompareメソッドが利用されます。

この記事でわかること
  • C#のstringクラスの基本操作
  • 文字列の結合とフォーマット方法
  • 文字列の検索と比較のテクニック
  • 文字列の変換とエンコーディング手法
  • 実践的な文字列操作の応用例

目次から探す

stringクラスの基本概要

C#におけるstringクラスは、文字列を扱うための基本的なデータ型です。

文字列は不変(immutable)であり、一度作成された文字列は変更できません。

この特性により、文字列の安全性が保たれ、複数の場所で同じ文字列を参照しても、意図しない変更が起こることはありません。

stringクラスは、文字列の作成、結合、検索、比較、変換など、さまざまな操作を行うためのメソッドを提供しています。

これにより、プログラマーは効率的に文字列を操作し、必要な情報を抽出したり、フォーマットしたりすることができます。

C#のstringクラスは、他の多くのプログラミング言語と同様に、文字列操作を簡単に行えるように設計されています。

これにより、開発者はアプリケーションの要件に応じて、柔軟に文字列を扱うことが可能です。

文字列の作成と初期化

リテラルでの文字列作成

C#では、文字列リテラルを使用して簡単に文字列を作成できます。

文字列リテラルは、ダブルクォーテーションで囲まれた文字の列です。

以下の例では、文字列リテラルを使って「こんにちは」と「世界」を作成しています。

string greeting = "こんにちは";
string world = "世界";
Console.WriteLine(greeting);
Console.WriteLine(world);
こんにちは
世界

変数からの文字列作成

既存の変数を使って新しい文字列を作成することもできます。

例えば、他の文字列を結合して新しい文字列を生成することが可能です。

string name = "太郎";
string message = "こんにちは、" + name + "さん!";
Console.WriteLine(message);
こんにちは、太郎さん!

特殊文字のエスケープシーケンス

文字列内で特定の文字を表現するために、エスケープシーケンスを使用します。

例えば、改行やタブなどの特殊文字を含めることができます。

以下は、改行を含む文字列の例です。

string text = "こんにちは。\n世界!";
Console.WriteLine(text);
こんにちは。
世界!

verbatim文字列リテラル(@を使った文字列)

verbatim文字列リテラルは、@を使って作成します。

この形式では、エスケープシーケンスを使用せずに、改行やタブをそのまま文字列に含めることができます。

ファイルパスなどに便利です。

string filePath = @"C:\Users\太郎\Documents\file.txt";
Console.WriteLine(filePath);
C:\Users\太郎\Documents\file.txt

文字列の結合とフォーマット

+演算子による結合

C#では、+演算子を使用して複数の文字列を結合することができます。

この方法は簡単で直感的ですが、大量の文字列を結合する場合はパフォーマンスに影響を与えることがあります。

string firstName = "太郎";
string lastName = "山田";
string fullName = firstName + " " + lastName;
Console.WriteLine(fullName);
太郎 山田

String.Concatメソッド

String.Concatメソッドを使用すると、複数の文字列を効率的に結合できます。

このメソッドは、引数として複数の文字列を受け取ります。

string firstName = "太郎";
string lastName = "山田";
string fullName = String.Concat(firstName, " ", lastName);
Console.WriteLine(fullName);
太郎 山田

String.Joinメソッド

String.Joinメソッドは、配列やコレクションの要素を指定した区切り文字で結合するために使用します。

これにより、リスト形式の文字列を簡単に作成できます。

string[] names = { "太郎", "次郎", "三郎" };
string joinedNames = String.Join(", ", names);
Console.WriteLine(joinedNames);
太郎, 次郎, 三郎

StringBuilderを使った効率的な結合

StringBuilderクラスは、文字列の結合や変更を効率的に行うためのクラスです。

大量の文字列を操作する場合に特に有用です。

以下の例では、StringBuilderを使用して文字列を結合しています。

using System.Text;
StringBuilder sb = new StringBuilder();
sb.Append("こんにちは");
sb.Append("、");
sb.Append("世界!");
string result = sb.ToString();
Console.WriteLine(result);
こんにちは、世界!

文字列のフォーマット:String.Formatと補間文字列

String.Formatメソッドを使用すると、文字列内に変数の値を埋め込むことができます。

また、C# 6.0以降では、補間文字列($を使った文字列)を使用することもできます。

string name = "太郎";
int age = 25;
// String.Formatを使用
string formattedString = String.Format("{0}さんは{1}歳です。", name, age);
Console.WriteLine(formattedString);
// 補間文字列を使用
string interpolatedString = $"{name}さんは{age}歳です。";
Console.WriteLine(interpolatedString);
太郎さんは25歳です。
太郎さんは25歳です。

文字列の検索と操作

部分文字列の取得:Substringメソッド

Substringメソッドを使用すると、指定した位置から始まる部分文字列を取得できます。

開始位置と取得する文字数を指定することができます。

string text = "こんにちは、世界!";
string subText = text.Substring(5, 3); // 5文字目から3文字を取得
Console.WriteLine(subText); // 出力結果: 世界
、世界

文字列の検索:IndexOfとLastIndexOf

IndexOfメソッドは、指定した文字列が最初に出現する位置を返します。

一方、LastIndexOfメソッドは、指定した文字列が最後に出現する位置を返します。

string text = "こんにちは、世界!こんにちは!";
int firstIndex = text.IndexOf("こんにちは"); // 最初の出現位置
int lastIndex = text.LastIndexOf("こんにちは"); // 最後の出現位置
Console.WriteLine("最初の出現位置: " + firstIndex);
Console.WriteLine("最後の出現位置: " + lastIndex);
最初の出現位置: 0
最後の出現位置: 9

文字列の存在確認:Containsメソッド

Containsメソッドを使用すると、指定した文字列が元の文字列に含まれているかどうかを確認できます。

結果は真偽値(trueまたはfalse)で返されます。

string text = "こんにちは、世界!";
bool containsHello = text.Contains("こんにちは");
Console.WriteLine(containsHello);
含まれているか: True

文字列の先頭・末尾の確認:StartsWithとEndsWith

StartsWithメソッドは、文字列が指定した文字列で始まるかどうかを確認します。

EndsWithメソッドは、文字列が指定した文字列で終わるかどうかを確認します。

string text = "こんにちは、世界!";
bool startsWithHello = text.StartsWith("こんにちは");
bool endsWithWorld = text.EndsWith("世界!");
Console.WriteLine("先頭で始まる: " + startsWithHello);
Console.WriteLine("末尾で終わる: " + endsWithWorld);
先頭で始まる: True
末尾で終わる: True

文字列の置換:Replaceメソッド

Replaceメソッドを使用すると、指定した文字列を別の文字列に置き換えることができます。

元の文字列は変更されず、新しい文字列が返されます。

string text = "こんにちは、世界!";
string replacedText = text.Replace("世界", "C#");
Console.WriteLine(replacedText);
こんにちは、C#!

文字列の比較

Equalsメソッドによる比較

Equalsメソッドは、2つの文字列が等しいかどうかを比較するために使用されます。

このメソッドは、オブジェクトの等価性を確認するためにオーバーライドされており、文字列の内容が同じであればtrueを返します。

string str1 = "こんにちは";
string str2 = "こんにちは";
bool areEqual = str1.Equals(str2);
Console.WriteLine(areEqual);
True

Compareメソッドによる比較

Compareメソッドは、2つの文字列を比較し、結果を整数で返します。

返される値は、最初の文字列が2番目の文字列より小さい場合は負の値、等しい場合は0、大きい場合は正の値になります。

string str1 = "apple";
string str2 = "banana";
int comparisonResult = String.Compare(str1, str2);
Console.WriteLine("比較結果: {0}", comparisonResult);
比較結果: -1

大文字・小文字を無視した比較

大文字・小文字を無視して文字列を比較する場合、String.EqualsメソッドString.CompareメソッドStringComparison列挙体を使用します。

これにより、ケースインセンシティブな比較が可能です。

string str1 = "こんにちは";
string str2 = "こんにちは";
bool areEqualIgnoreCase = str1.Equals(str2, StringComparison.OrdinalIgnoreCase);
Console.WriteLine("大文字小文字を無視した比較: " + areEqualIgnoreCase);
大文字小文字を無視した比較: True

==演算子とEqualsの違い

==演算子は、2つの文字列が同じ内容を持っているかどうかを比較します。

一方、Equalsメソッドも文字列の内容が等しいかどうかを比較しますが、==演算子はC#のstring型において内容の比較としてオーバーロードされています。

通常、文字列の内容を比較する場合はEqualsメソッドを使用することが推奨されますが、==演算子も同様に内容の比較を行います。

参照の比較を行いたい場合は、Object.ReferenceEqualsメソッドを使用します。

string str1 = new string("こんにちは".ToCharArray());
string str2 = new string("こんにちは");
bool referenceEqual = Object.ReferenceEquals(str1, str2); // 参照の比較
bool contentEqual = str1.Equals(str2); // 内容の比較
Console.WriteLine("参照が等しいか: " + referenceEqual);
Console.WriteLine("内容が等しいか: " + contentEqual);
参照が等しいか: False
内容が等しいか: True

文字列の変換

大文字・小文字の変換:ToUpperとToLower

ToUpperメソッドは、文字列内のすべての文字を大文字に変換します。

一方、ToLowerメソッドは、すべての文字を小文字に変換します。

これにより、文字列のフォーマットを統一することができます。

string originalText = "こんにちは、世界!";
string upperText = originalText.ToUpper(); // 大文字に変換
string lowerText = originalText.ToLower(); // 小文字に変換
Console.WriteLine("大文字: " + upperText);
Console.WriteLine("小文字: " + lowerText);
大文字: こんにちは、世界!
小文字: こんにちは、世界!

文字列のトリミング:Trim、TrimStart、TrimEnd

Trimメソッドは、文字列の先頭と末尾から空白文字を削除します。

TrimStartメソッドは先頭の空白を、TrimEndメソッドは末尾の空白を削除します。

これにより、不要な空白を取り除くことができます。

string textWithSpaces = "   こんにちは、世界!   ";
string trimmedText = textWithSpaces.Trim(); // 両端の空白を削除
string trimmedStartText = textWithSpaces.TrimStart(); // 先頭の空白を削除
string trimmedEndText = textWithSpaces.TrimEnd(); // 末尾の空白を削除
Console.WriteLine("トリミング後: " + trimmedText);
Console.WriteLine("先頭の空白を削除: " + trimmedStartText);
Console.WriteLine("末尾の空白を削除: " + trimmedEndText);
トリミング後: こんにちは、世界!
先頭の空白を削除: こんにちは、世界!   
末尾の空白を削除:    こんにちは、世界!

文字列の分割:Splitメソッド

Splitメソッドを使用すると、指定した区切り文字で文字列を分割し、配列として返します。

これにより、カンマ区切りやスペース区切りのデータを簡単に処理できます。

string csv = "りんご,バナナ,オレンジ";
string[] fruits = csv.Split(','); // カンマで分割
Console.WriteLine("分割結果:");
foreach (string fruit in fruits)
{
    Console.WriteLine(fruit);
}
分割結果:
りんご
バナナ
オレンジ

文字列から数値への変換:ParseとTryParse

文字列を数値に変換するためには、ParseメソッドTryParseメソッドを使用します。

Parseメソッドは、変換が成功すると数値を返しますが、失敗すると例外をスローします。

一方、TryParseメソッドは、変換が成功したかどうかを真偽値で返し、失敗した場合でも例外をスローしません。

string numberString = "12345";
int number;
// Parseを使用
number = int.Parse(numberString);
// TryParseを使用
bool success = int.TryParse(numberString, out number);
Console.WriteLine("Parse結果: " + number);
Console.WriteLine("TryParse成功: " + success + ", 数値: " + number);
Parse結果: 12345
TryParse成功: True, 数値: 12345

文字列のエンコーディング

文字列とバイト配列の相互変換:Encodingクラス

C#では、Encodingクラスを使用して文字列とバイト配列の相互変換を行うことができます。

GetBytesメソッドを使用して文字列をバイト配列に変換し、GetStringメソッドを使用してバイト配列を文字列に変換します。

using System.Text;
string originalText = "こんにちは";
Encoding encoding = Encoding.UTF8;
// 文字列をバイト配列に変換
byte[] byteArray = encoding.GetBytes(originalText);
// バイト配列を文字列に変換
string decodedText = encoding.GetString(byteArray);
Console.WriteLine("元の文字列: " + originalText);
Console.WriteLine("デコード後の文字列: " + decodedText);
元の文字列: こんにちは
デコード後の文字列: こんにちは

UTF-8、UTF-16、ASCIIの違い

エンコーディング方式にはいくつかの種類がありますが、特に一般的なものにUTF-8、UTF-16、ASCIIがあります。

スクロールできます
エンコーディング特徴
UTF-8可変長エンコーディング。
ASCIIと互換性があり、1バイトから4バイトで文字を表現。多言語対応。
UTF-16固定長エンコーディング。
2バイトまたは4バイトで文字を表現。主にWindows環境で使用。
ASCII7ビットエンコーディング。
英数字と一部の記号のみを表現。日本語などの多言語には対応していない。

文字列のエンコードとデコード

文字列のエンコードは、文字列を特定のエンコーディング方式でバイト配列に変換するプロセスです。

デコードは、バイト配列を元の文字列に戻すプロセスです。

以下の例では、UTF-8エンコーディングを使用して文字列をエンコードし、デコードしています。

using System;
using System.Text;
string originalText = "こんにちは";
Encoding encoding = Encoding.UTF8;
// エンコード
byte[] encodedBytes = encoding.GetBytes(originalText);
// デコード
string decodedText = encoding.GetString(encodedBytes);
Console.WriteLine("エンコード後のバイト配列: {0}", BitConverter.ToString(encodedBytes));
Console.WriteLine("デコード後の文字列: {0}", decodedText);
エンコード後のバイト配列: E3-81-93-E3-82-93-E3-81-AB-E3-81-A1-E3-81-AF
デコード後の文字列: こんにちは

このように、エンコーディングとデコーディングを使用することで、異なるシステム間で文字列データを正しくやり取りすることが可能になります。

応用例:文字列操作の実践

ファイルパスの操作

C#では、ファイルパスを操作するためにPathクラスを使用します。

このクラスを使うことで、ファイル名の取得や拡張子の変更、ディレクトリの結合などが簡単に行えます。

using System.IO;
string filePath = @"C:\Users\太郎\Documents\file.txt";
// ファイル名の取得
string fileName = Path.GetFileName(filePath); // file.txt
// 拡張子の取得
string fileExtension = Path.GetExtension(filePath); // .txt
// ディレクトリの取得
string directory = Path.GetDirectoryName(filePath); // C:\Users\太郎\Documents

Console.WriteLine("ファイル名: " + fileName);
Console.WriteLine("拡張子: " + fileExtension);
Console.WriteLine("ディレクトリ: " + directory);
ファイル名: file.txt
拡張子: .txt
ディレクトリ: C:\Users\太郎\Documents

URLの操作とクエリパラメータの解析

URLを操作するためには、Uriクラスを使用します。

このクラスを使うことで、URLの各部分を簡単に取得したり、クエリパラメータを解析したりできます。

string url = "https://example.com/search?q=こんにちは&lang=ja";
Uri uri = new Uri(url);
// クエリパラメータの取得
var query = System.Web.HttpUtility.ParseQueryString(uri.Query);
string searchQuery = query["q"]; // こんにちは
string language = query["lang"]; // ja
Console.WriteLine("検索クエリ: " + searchQuery);
Console.WriteLine("言語: " + language);
検索クエリ: こんにちは
言語: ja

CSVデータのパース

CSV形式のデータをパースするためには、Splitメソッドを使用してカンマで分割し、各フィールドを取得します。

以下の例では、CSVデータを解析して各フィールドを表示しています。

string csvData = "名前,年齢,国\n太郎,25,日本\n次郎,30,日本";
string[] lines = csvData.Split('\n');
foreach (string line in lines)
{
    string[] fields = line.Split(',');
    Console.WriteLine($"名前: {fields[0]}, 年齢: {fields[1]}, 国: {fields[2]}");
}
名前: 名前, 年齢: 年齢, 国: 国
名前: 太郎, 年齢: 25, 国: 日本
名前: 次郎, 年齢: 30, 国: 日本

正規表現を使った文字列操作

正規表現を使用すると、特定のパターンに基づいて文字列を検索、置換、分割することができます。

C#では、Regexクラスを使用して正規表現を扱います。

using System.Text.RegularExpressions;
string input = "メールアドレス: example@example.com";
string pattern = @"\w+@\w+\.\w+";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
    Console.WriteLine($"見つかったメールアドレス: {match.Value}");
}
見つかったメールアドレス: example@example.com

文字列の暗号化と復号化

文字列を暗号化するためには、Aesクラスを使用して対称暗号を実装することができます。

以下の例では、文字列を暗号化し、復号化する方法を示しています。

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

class Program
{
    static void Main()
    {
        string originalText = "秘密のメッセージ";
        byte[] key = Encoding.UTF8.GetBytes("1234567890123456"); // 16バイトのキー
        byte[] iv = Encoding.UTF8.GetBytes("1234567890123456"); // 16バイトのIV
        byte[] encrypted; // 暗号化されたデータを格納する変数

        // 暗号化
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter sw = new StreamWriter(cs))
                    {
                        sw.Write(originalText);
                    }
                    encrypted = ms.ToArray(); // 暗号化されたデータを変数に格納
                }
            }
        }

        Console.WriteLine($"暗号化されたデータ: {Convert.ToBase64String(encrypted)}");

        // 復号化
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;
            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
            using (MemoryStream ms = new MemoryStream(encrypted))
            {
                using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader sr = new StreamReader(cs))
                    {
                        string decryptedText = sr.ReadToEnd();
                        Console.WriteLine($"復号化されたデータ: {decryptedText}");
                    }
                }
            }
        }
    }
}
暗号化されたデータ: U/DFNss2vp9Eu94ddK14KdfBUZay4k4no4pP4T+bsz0=
復号化されたデータ: 秘密のメッセージ

このように、C#ではさまざまな文字列操作を行うための機能が豊富に用意されており、実践的なアプリケーションに応じて柔軟に利用することができます。

よくある質問

文字列の結合で+演算子を使うのは非推奨ですか?

+演算子を使用して文字列を結合することは可能ですが、大量の文字列を結合する場合には非推奨とされています。

これは、+演算子を使用すると、毎回新しい文字列オブジェクトが生成されるため、パフォーマンスに影響を与えるからです。

特にループ内での結合では、StringBuilderを使用することが推奨されます。

StringBuilderは内部で可変の文字列を管理し、効率的に文字列を結合できます。

StringBuilderはいつ使うべきですか?

StringBuilderは、特に以下のような状況で使用することが推奨されます:

  • 大量の文字列を結合する場合(例:ループ内での結合)。
  • 文字列の変更が頻繁に行われる場合(例:文字列の追加や削除)。
  • パフォーマンスが重要なアプリケーションで、文字列操作がボトルネックになる可能性がある場合。

StringBuilderを使用することで、メモリの使用効率が向上し、パフォーマンスが改善されます。

==演算子とEqualsメソッドの違いは何ですか?

==演算子とEqualsメソッドは、文字列の比較に使用されますが、比較の方法が異なります。

  • ==演算子は、2つの文字列が同じ参照を指しているかどうかを比較します。

つまり、同じオブジェクトであるかどうかを確認します。

  • Equalsメソッドは、2つの文字列の内容が等しいかどうかを比較します。

内容が同じであれば、異なるオブジェクトでもtrueを返します。

このため、文字列の内容を比較する場合はEqualsメソッドを使用することが推奨されます。

==演算子は、参照の比較が必要な場合に使用します。

まとめ

この記事では、C#のstringクラスに関する基本的な操作から応用例まで幅広く解説しました。

文字列の作成、結合、検索、比較、変換、エンコーディングなど、さまざまな機能を活用することで、効率的に文字列を扱うことが可能です。

これらの知識を活かして、実際のプログラミングにおいて文字列操作を行う際には、適切なメソッドやクラスを選択し、パフォーマンスを意識したコーディングを心がけてください。

当サイトはリンクフリーです。出典元を明記していただければ、ご自由に引用していただいて構いません。

関連カテゴリーから探す

  • URLをコピーしました!
目次から探す