文字列内の「位置」を検索する
C#で文字列を操作する際、「この文字列にキーワードが含まれているか(Contains)」だけでなく、「そのキーワードがどの位置(インデックス)から始まっているか」を知りたい場合があります。
例えば、"ERROR: 接続がタイムアウトしました。"というログ文字列から、"ERROR: "というプレフィックスを除いた、実際のエラーメッセージ本体("接続がタイムアウトしました。")を取得したい場合、"ERROR: "がどの位置にあるかを知る必要があります。
この役割を担うのが string.IndexOf メソッドです。
string.IndexOf メソッドの基本
IndexOf メソッドは、対象の文字列内で、引数として渡された部分文字列(キーワード)が最初に出現する開始位置(インデックス)をint型で返します。
重要なルール:
- インデックスは
0(ゼロ)から始まります: 文字列の先頭の文字は0番目です。 - 見つからなかった場合は
-1を返します: この-1という戻り値は、キーワードが存在しなかったことを示すシグナルとして非常に重要です。
IndexOf は、デフォルトで大文字と小文字を厳密に区別します。
コード例: 基本的な検索
using System;
public class IndexOfBasicExample
{
public static void Main()
{
string logLine = "INFO: Process completed successfully. UserID: 101";
// 1. "Process" という単語を検索
string keyword1 = "Process";
int index1 = logLine.IndexOf(keyword1);
// "INFO: " (6文字) の次なので、インデックス 6 が返る
Console.WriteLine($"'{keyword1}' の位置: {index1}");
// 2. "ERROR" という単語を検索
string keyword2 = "ERROR";
int index2 = logLine.IndexOf(keyword2);
// 見つからないため、-1 が返る
Console.WriteLine($"'{keyword2}' の位置: {index2}");
// 3. 'if' 文での活用 (存在チェック)
string keyword3 = "UserID:";
int index3 = logLine.IndexOf(keyword3);
// IndexOf の結果が -1 ではない(= 0以上)かで存在を判定
if (index3 != -1)
{
Console.WriteLine($"'{keyword3}' が見つかりました。位置: {index3}");
}
else
{
Console.WriteLine($"'{keyword3}' は見つかりませんでした。");
}
}
}
出力結果:
'Process' の位置: 6
'ERROR' の位置: -1
'UserID:' が見つかりました。位置: 32
応用1: 検索開始位置を指定する
IndexOf メソッドには、検索を開始する位置(インデックス)を指定できるオーバーロード(引数が異なる同名メソッド)があります。
string.IndexOf(string value, int startIndex)
これは、2番目以降のキーワードを見つけたい場合や、特定のセクション以降を検索対象としたい場合に便利です。
コード例: 2番目のキーワードを検索
using System;
public class IndexOfNextExample
{
public static void Main()
{
string text = "File: data.csv, Status: OK, File: report.csv, Status: Pending";
// 1. 最初の "File:" を検索
int firstIndex = text.IndexOf("File:");
Console.WriteLine($"1番目の 'File:' の位置: {firstIndex}"); // 0
// 2. 最初の "File:" が見つかった位置 (0) の「次」から、2番目の "File:" を検索
int startIndex = firstIndex + 1;
int secondIndex = text.IndexOf("File:", startIndex);
Console.WriteLine($"2番目の 'File:' の位置: {secondIndex}"); // 27
}
}
出力結果:
1番目の 'File:' の位置: 0
2番目の 'File:' の位置: 27
応用2: 大文字・小文字を区別せずに検索する
デフォルトのIndexOfは "File" と "file" を区別します。大文字・小文字を無視して検索したい場合は、StringComparison 列挙型を指定するオーバーロードを使用します。
string.IndexOf(string value, StringComparison comparisonType)
コード例: OrdinalIgnoreCase
StringComparison.OrdinalIgnoreCase を指定すると、大文字・小文字を区別せずに、高速に検索を行います。
using System;
public class IndexOfIgnoreCaseExample
{
public static void Main()
{
string message = "Request failed with status [ERROR]";
string keyword = "[error]"; // 小文字で検索
// 比較ルール: 大文字・小文字を無視
StringComparison rule = StringComparison.OrdinalIgnoreCase;
// "error" (小文字) で "[ERROR]" (大文字) を検索
int index = message.IndexOf(keyword, rule);
if (index >= 0) // -1 ではない
{
Console.WriteLine($"キーワードが位置 {index} で見つかりました (大文字/小文字 無視)。");
}
else
{
Console.WriteLine("キーワードは見つかりませんでした。");
}
}
}
出力結果:
キーワードが位置 26 で見つかりました (大文字/小文字 無視)。
まとめ
string.IndexOf メソッドは、文字列内における部分文字列の「位置(インデックス)」を int 型で返します。
0から始まるインデックスが返されます。- キーワードが見つからない場合は
-1が返されます。 if (index != -1)(またはindex >= 0)という形で、Containsメソッドのように存在判定にも使用できます。- 検索開始位置(
startIndex)や比較ルール(StringComparison)を指定することで、より柔軟な検索が可能です。
