演習 - 文字列の IndexOf() および Substring() ヘルパー メソッドを使用する

完了

この演習では、IndexOf() メソッドを使用して、大きい文字列の中から 1 つ以上の文字列の位置を見つけます。 指定した文字位置の後の大きな文字列の一部を返すには、Substring() メソッドを使用します。

また、Substring() メソッドのオーバーロードされたバージョンを使用して、文字列内に指定した位置の後に返す文字の長さを設定することもできます。

コーディング環境を準備する

このモジュールには、デモ コードをビルドして実行するプロセスをガイドする実践的なアクティビティが含まれています。 これらのアクティビティを完了するには、開発環境として Visual Studio Code を使用することをお勧めします。 これらのアクティビティに Visual Studio Code を使用すると、世界中のプロフェッショナルが使用する開発環境でコードの記述と実行をより快適に行うことができます。

Note

この C# シリーズの Microsoft Learn を完了している場合は、コード サンプル用のプロジェクト フォルダーが既に作成されている場合があります。 その場合は、手順の次のセクションをスキップし、前の演習で使用した Project.cs ファイル内のコードを削除できます。

  1. Visual Studio Code を開きます。

    Visual Studio Code は、Windows の [スタート] メニュー (別の OS の場合は同等のリソース) を使用して開くことができます。

  2. Visual Studio Code の [ファイル] メニューで、[フォルダーを開く] を選択します。

  3. [フォルダーを開く] ダイアログで、Windows の [デスクトップ] フォルダーに移動します。

    コード プロジェクトを保持するフォルダーの場所が異なる場合は、代わりにそのフォルダーの場所を使用できます。 このトレーニングでは、見つけやすく覚えやすい場所を用意することが重要です。

  4. [フォルダーを開く] ダイアログで、[フォルダーの選択] を選択します。

    作成者を信頼するかどうかを確認するセキュリティ ダイアログが表示された場合は、[はい] を選択します。

  5. Visual Studio Code の [ターミナル] メニューで、[新しいターミナル] を選択します。

    [ターミナル] パネルのコマンド プロンプトに、現在のフォルダーのフォルダー パスが表示されることを確認します。 次に例を示します。

    C:\Users\someuser\Desktop>
    
  6. ターミナルのコマンド プロンプトで、指定したフォルダーに新しいコンソール アプリケーションを作成するには、「dotnet new console -o ./CsharpProjects/TestProject」と入力してから、Enter キーを押します。

    この .NET CLI コマンドでは、.NET プログラム テンプレートを使用して、指定したフォルダーの場所に新しい C# コンソール アプリケーション プロジェクトを作成します。 このコマンドで [CsharpProjects] と [TestProject] のフォルダーが自動的に作成され、.csproj ファイルの名前として TestProject が使用されます。

  7. [エクスプローラー] パネルで、[CsharpProjects] フォルダーを展開します。

    [TestProject] フォルダーと、Program.cs という名前の C# プログラム ファイルと、TestProject.csproj という名前の C# プロジェクト ファイルの 2 つが表示されるはずです。

  8. [エクスプローラー] パネルの [エディター] パネルにコード ファイルを表示するには、[Program.cs] を選択します。

  9. 既存のコード行を削除します。

    この C# コンソール プロジェクトを使用して、このモジュール中のコード サンプルの作成、ビルド、実行を行います。

  10. [ターミナル] パネルを閉じます。

文字列に埋め込まれているかっこのペアを検索するコードを書く

  1. Visual Studio Code が開き、[エディター] パネルに Program.cs が表示されていることを確認してください。

    Note

    Program.cs は空になっているはずです。 そうでない場合は、すべてのコード行を選択して削除します。

  2. Visual Studio Code エディターに次のコードを入力します。

    string message = "Find what is (inside the parentheses)";
    
    int openingPosition = message.IndexOf('(');
    int closingPosition = message.IndexOf(')');
    
    Console.WriteLine(openingPosition);
    Console.WriteLine(closingPosition);
    
  3. Visual Studio Code の [ファイル] メニューで、[保存] を選択します。

    コードをビルドまたは実行する前に、Program.cs ファイルを保存する必要があります。

  4. [エクスプローラー] パネルで、TestProject フォルダーの場所にあるターミナルを開くには、TestProject を右クリックし、[統合ターミナルで開く] を選択します。

    ターミナル パネルが開き、ターミナルが TestProject フォルダーの場所に対して開かれていることを示すコマンド プロンプトが含まれているはずです。

  5. コードを実行するには、ターミナルのコマンド プロンプトで、「dotnet run」と入力し、Enter キーを押します。

    Note

    "実行するプロジェクトが見つかりませんでした" というメッセージが表示された場合は、ターミナルのコマンド プロンプトに、予期されている TestProject フォルダーの場所が表示されていることを確かめます。 例: C:\Users\someuser\Desktop\csharpprojects\TestProject>

    次の出力が表示されます。

    13
    36
    

    この場合、文字 ( のインデックスは 13 です。 これらの値は 0 から始まるので、文字列内の 14 文字目であることに注意してください。 文字 ) のインデックスは 36 です。

    2 つのインデックスが得られたので、それらを境界として使って、それらの間にある値を取得できます。

かっこの間の値を取得するコードを追加する

  1. Visual Studio Code エディターで次のようにコードを更新してください。

    string message = "Find what is (inside the parentheses)";
    
    int openingPosition = message.IndexOf('(');
    int closingPosition = message.IndexOf(')');
    
    // Console.WriteLine(openingPosition);
    // Console.WriteLine(closingPosition);
    
    int length = closingPosition - openingPosition;
    Console.WriteLine(message.Substring(openingPosition, length));
    
  2. コード ファイルを保存してから、Visual Studio Code を使ってコードを実行します。 次の出力が表示されます。

    (inside the parentheses
    

    Substring() メソッドには、取得する開始位置と文字数 (長さ) が必要です。 そのため、length という名前の一時変数内の長さを計算し、それを openingPosition の値と共に渡して、かっこ内の文字列を取得します。

    ほぼ意図した結果になりますが、出力に開始小かっこが含まれています。 この演習では、かっこを含めることは望ましくありません。 出力からかっこを削除するには、かっこ自体のインデックスをスキップするようにコードを更新する必要があります。

サブ文字列の開始位置を変更する

  1. Visual Studio Code エディターで次のようにコードを更新してください。

    string message = "Find what is (inside the parentheses)";
    
    int openingPosition = message.IndexOf('(');
    int closingPosition = message.IndexOf(')');
    
    openingPosition += 1;
    
    int length = closingPosition - openingPosition;
    Console.WriteLine(message.Substring(openingPosition, length));
    
  2. コード ファイルを保存してから、Visual Studio Code を使ってコードを実行します。 次の出力が表示されます。

    inside the parentheses
    
  3. 少し時間をかけ、前のコードと行 openingPosition += 1; を確認してください。

    openingPosition1 だけ増やすことで、開始小かっこ文字をスキップします。

    1 を使用している理由は、それが文字の長さであるためです。 <div>--- など、より長い文字列の後で始まる値を見つけたい場合は、その文字列の長さを代わりに使用します。

  4. Visual Studio Code エディターで次のようにコードを更新してください。

    string message = "What is the value <span>between the tags</span>?";
    
    int openingPosition = message.IndexOf("<span>");
    int closingPosition = message.IndexOf("</span>");
    
    openingPosition += 6;
    int length = closingPosition - openingPosition;
    Console.WriteLine(message.Substring(openingPosition, length));
    
  5. 少し時間をかけ、前のコードと行 openingPosition += 6; を確認してください。

    前述のコード スニペットでは、開始と終了の <span> タグの内側にある値を検索する方法が示されています。

    この例では、openingPosition にオフセットとして 6 を追加し、サブ文字列の長さを計算しています。

マジック値を避ける

前のコード リストの "<span>" のようにハードコーディングされた文字列は "マジック文字列" と呼ばれ、6 のようなハードコーディングされた数値は "マジック ナンバー" と呼ばれます。 これらの "マジック" 値は、さまざまな理由から望ましくありません。可能であれば、避ける必要があります。

  1. 前のコードを確認して、コード内で文字列 "<span>" を複数回ハードコーディングしたが、そのうちの 1 つのインスタンスのスペルを "<sapn>" と書き間違えた場合に、コードがどのように壊れるかを検討してください。

    値が文字列内にあるため、コンパイラはコンパイル時に "<sapn>" をキャッチしません。 ミススペルは実行時の問題に繋がり、コードの複雑さによっては、追跡が困難となる場合があります。

    さらに、文字列 "<span>" をより短い "<div>" に変更したのに、値 65 に変更するのを忘れた場合、コードは望んだ結果を生みません。

  2. Visual Studio Code エディターで次のようにコードを更新してください。

    string message = "What is the value <span>between the tags</span>?";
    
    const string openSpan = "<span>";
    const string closeSpan = "</span>";
    
    int openingPosition = message.IndexOf(openSpan);
    int closingPosition = message.IndexOf(closeSpan);
    
    openingPosition += openSpan.Length;
    int length = closingPosition - openingPosition;
    Console.WriteLine(message.Substring(openingPosition, length));
    
  3. 更新されたコードと、const string openSpan = "<span>"; で使用されているキーワード const を、時間をかけて調べてください。

    このコードでは、const キーワードで定数を使用します。 定数を使用すると、値を変更できない変数を定義して、初期化することができます。 コードの残りの部分でその値が必要になったときは、常にその定数を使用します。 これにより、値の定義は 1 回だけであることと、変数 const のミススペルがコンパイラによってキャッチされることが保証されます。

    前のコード リストは、前のセクションで調べたのと同じコードを記述するより安全な方法です。 openSpan の値が <div> に変化した場合、Length プロパティが使用されているコード行は引き続き有効です。

要点

このユニットでは多くの要素を扱いました。 覚えておく必要がある最も重要なことは次のとおりです。

  • IndexOf() を使うと、別の文字列内での文字または文字列の最初の位置を取得できます。
  • IndexOf() では、一致するものが見つからない場合は -1 が返されます。
  • Substring() を使うと、開始位置と省略可能な長さを指定して、文字列の指定した部分だけを取得できます。
  • 多くの場合、問題を解決する方法は複数あります。 ここでは、特定の文字または文字列のすべてのインスタンスを検索するために、2 つの異なる手法を使いました。
  • ハード コーディングされたマジック値の使用は避けてください。 代わりに、const 変数を定義します。 定数変数の値は、初期化後に変更することはできません。

知識を確認

1.

string myString = "C# Time"; の場合、myString.IndexOf('C'); の戻り値は何ですか?