閉じる

【C#】Containsで文字列の含む判定!大文字小文字の区別や複数条件も解説

C#での開発において、文字列の中に特定のテキストが含まれているかどうかを確認する処理は、避けては通れないほど頻繁に登場します。

ユーザー入力のバリデーション、ログファイルの検索、データのフィルタリングなど、その用途は多岐にわたります。

C#にはこれを行うための標準的なメソッドとしてContainsが用意されていますが、単純な判定だけでなく、大文字・小文字の区別を無視したい場合や、複数のキーワードを一度に検索したい場合など、実務では一工夫必要な場面も多いです。

本記事では、C#のContainsメソッドを基礎から応用まで徹底的に解説し、現場で役立つ実践的なテクニックを紹介します。

Containsメソッドの基本的な使い方

C#のstring.Containsメソッドは、対象となる文字列の中に、指定した部分文字列が存在するかどうかをbool型(trueまたはfalse)で返却するメソッドです。

基本的な構文と動作

まずは最もシンプルな使い方を見てみましょう。

このメソッドはstringクラスのインスタンスメソッドとして定義されています。

C#
using System;

class Program
{
    static void Main()
    {
        string message = "C#は非常に強力な言語です。";
        string keyword = "強力";

        // 文字列が含まれているか判定
        bool result = message.Contains(keyword);

        Console.WriteLine($"元の文字列: {message}");
        Console.WriteLine($"検索キーワード: {keyword}");
        Console.WriteLine($"判定結果: {result}");
    }
}
実行結果
元の文字列: C#は非常に強力な言語です。
検索キーワード: 強力
判定結果: True

この例では、messageの中に「強力」という文字列が含まれているため、trueが返されます。

もし含まれていない場合はfalseとなります。

デフォルトでの大文字・小文字の区別

標準的なContainsメソッドを使用する場合、大文字と小文字は厳密に区別されるという点に注意が必要です。

C#
using System;

class Program
{
    static void Main()
    {
        string text = "Hello World";

        // 大文字小文字が一致する場合
        Console.WriteLine(text.Contains("Hello")); // True

        // 大文字小文字が異なる場合
        Console.WriteLine(text.Contains("hello")); // False
    }
}
実行結果
True
False

このように、一文字でもケース(大文字・小文字)が異なるとfalseと判定されます。

検索システムなどを作る際には、この挙動が不都合になることが多いため、次のセクションで解説する対処法を覚えることが重要です。

大文字・小文字を区別せずに判定する方法

ユーザーの検索意図に合わせる場合、大文字・小文字を無視(Case-insensitive)して判定したい場面が多々あります。

現代の.NET( .NET Core 2.0以降や.NET 5/6/7/8など)では、Containsメソッドの第2引数に比較オプションを指定するのが最も推奨される方法です。

StringComparison列挙型を利用する

StringComparison.OrdinalIgnoreCaseを指定することで、言語文化に依存しない高速な「大文字小文字を無視した比較」が可能になります。

C#
using System;

class Program
{
    static void Main()
    {
        string title = "Learning C# Programming";
        string searchWord = "c#";

        // StringComparison.OrdinalIgnoreCase を使用して大文字小文字を無視
        bool isMatch = title.Contains(searchWord, StringComparison.OrdinalIgnoreCase);

        Console.WriteLine($"対象: {title}");
        Console.WriteLine($"検索: {searchWord}");
        Console.WriteLine($"判定結果 (無視設定): {isMatch}");
    }
}
実行結果
対象: Learning C# Programming
検索: c#
判定結果 (無視設定): True

この方法は非常にスマートで、かつパフォーマンスも良好です。

古い.NET Framework環境(4.x以前)を使用している場合は、このオーバーロードが存在しないため、次に紹介する手法を用いる必要があります。

ToUpperやToLowerによる変換での対応

古い環境や、何らかの制約がある場合には、一度両方の文字列を大文字または小文字に変換してから判定する方法もあります。

C#
using System;

class Program
{
    static void Main()
    {
        string target = "DotNet Framework";
        string word = "dotnet";

        // 両方を小文字に変換してから比較
        bool result = target.ToLower().Contains(word.ToLower());

        Console.WriteLine($"結果: {result}");
    }
}
実行結果
結果: True

ただし、この方法は新しい文字列インスタンスを生成するため、メモリ効率やパフォーマンスの面で不利になる可能性があります。

ループ内で大量に処理を行う場合は、前述のStringComparisonを利用するべきです。

複数の文字列を含むか判定する方法

実務では「AまたはBが含まれているか(OR条件)」「AとBの両方が含まれているか(AND条件)」といった複雑な判定が求められます。

これをif文で何重にも書くのはスマートではありません。

LINQを活用したOR条件の判定(Any)

「キーワードリストのうち、いずれかが含まれているか」を判定するには、LINQのAnyメソッドを組み合わせるのが最適です。

C#
using System;
using System.Linq;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        string content = "本日は晴天なり。プログラミング日和です。";
        string[] keywords = { "雨", "曇り", "晴天" };

        // キーワードのいずれかが含まれているか
        bool containsAny = keywords.Any(k => content.Contains(k));

        Console.WriteLine($"いずれかを含む: {containsAny}");
    }
}
実行結果
いずれかを含む: True

keywords.Any(...)は、条件を満たす要素が一つでも見つかった瞬間に処理を終了するため、効率的です。

LINQを活用したAND条件の判定(All)

逆に「指定したすべてのキーワードが含まれているか」を判定したい場合は、Allメソッドを使用します。

C#
using System;
using System.Linq;

class Program
{
    static void Main()
    {
        string bio = "Software Developer based in Tokyo, Japan.";
        string[] requiredWords = { "Developer", "Tokyo", "Japan" };

        // すべてのキーワードが含まれているか
        bool containsAll = requiredWords.All(w => bio.Contains(w));

        Console.WriteLine($"すべてを含む: {containsAll}");
    }
}
実行結果
すべてを含む: True

正規表現(Regex)を使用した高度な判定

より複雑なパターンマッチング(例えば、単語の境界を意識したり、特定の順序で並んでいるかなど)が必要な場合は、System.Text.RegularExpressions.Regexクラスを利用します。

C#
using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main()
    {
        string text = "The quick brown fox jumps over the lazy dog.";
        
        // 「fox」または「cat」が含まれているか(大文字小文字無視)
        string pattern = "fox|cat";
        bool isMatch = Regex.IsMatch(text, pattern, RegexOptions.IgnoreCase);

        Console.WriteLine($"Regex判定結果: {isMatch}");
    }
}
実行結果
Regex判定結果: True

正規表現は強力ですが、単純な文字列検索に比べると処理コストが高いため、必要最低限の場面で使用するのがベストです。

コレクション(配列・リスト)でのContains

ここまでは「文字列の中の部分一致」について解説してきましたが、C#には「リストの中に特定の要素が完全に一致して存在するか」を確認するためのContainsも存在します。

これらは混同されやすいため整理しておきましょう。

種類対象判定内容
string.Contains文字列部分一致 (Substring)
List<T>.Containsリスト完全一致 (Exact Match)
Enumerable.Contains配列等完全一致 (Exact Match)

List<string>での使用例

リストの中に、特定の文字列と「丸ごと一致」する要素があるかを確認します。

C#
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<string> userList = new List<string> { "Alice", "Bob", "Charlie" };

        // 「Bob」という要素がリストにあるか
        bool hasBob = userList.Contains("Bob");
        // 「Al」という要素があるか(部分一致ではないためFalse)
        bool hasAl = userList.Contains("Al");

        Console.WriteLine($"Bobが存在するか: {hasBob}");
        Console.WriteLine($"Alが存在するか: {hasAl}");
    }
}
実行結果
Bobが存在するか: True
Alが存在するか: False

もし、リストの各要素に対して「部分一致」で検索したい場合は、前述のAnyメソッドを使い、userList.Any(u => u.Contains("Al"))のように記述する必要があります。

実践的な注意点とパフォーマンス

Containsを使う際に初心者が陥りやすい罠や、より安全にコードを書くためのテクニックを解説します。

Null判定とNull条件演算子

対象の文字列がnullであった場合、Containsを呼び出すとNullReferenceExceptionが発生してアプリがクラッシュします。

これを防ぐために、C# 6.0以降で導入された「Null条件演算子(?.)」を活用しましょう。

C#
using System;

class Program
{
    static void Main()
    {
        string input = null;

        // 安全な呼び出し方
        // inputがnullならnullを返し、その結果を??でfalseに変換する
        bool result = input?.Contains("C#") ?? false;

        Console.WriteLine($"Nullセーフな判定結果: {result}");
    }
}
実行結果
Nullセーフな判定結果: False

このように記述することで、変数がnullであっても例外を投げずにfalse(含まれていない)として安全に処理を続行できます。

空文字(“”)の判定

Containsに空文字を指定した場合、どのような挙動になるでしょうか?

C#
string text = "Hello";
bool result = text.Contains(""); // 結果はどうなる?

答えは常にtrueです。

いかなる文字列も(空文字自身も含め)、空文字を内包しているとみなされる仕様になっています。

これはバグの原因になりやすいため、検索キーワードがユーザー入力から来る場合は、事前にstring.IsNullOrEmptyでチェックを行うのが定石です。

パフォーマンスを意識する場合

数百万行のテキストデータから特定の文字を探すような場合、Containsを愚直に繰り返すと時間がかかることがあります。

静的な検索

対象が変わらず、何度も検索する場合はHashSet<string>などへの格納を検討する(完全一致の場合)。

Span<T>の利用

.NET Core以降の高度な最適化では、ReadOnlySpan<char>を利用することで、メモリ割り当てを最小限に抑えた高速な検索が可能です。

大文字小文字無視

すでに述べた通り、ToUpper()をループ内で繰り返すのは避け、StringComparison.OrdinalIgnoreCaseを使用してください。

まとめ

C#のContainsメソッドは、非常にシンプルでありながら、奥の深いメソッドです。

基本的には「文字列が含まれているか」をtrue/falseで返すものですが、実務においては以下のポイントを意識することが「書けるエンジニア」への第一歩となります。

  • 大文字小文字の制御: 第2引数でStringComparisonを指定する。
  • 複数条件: LINQのAnyAllを活用して、可読性の高いコードを書く。
  • 安全性: Null条件演算子?.を使い、実行時エラーを未然に防ぐ。
  • 使い分け: 文字列の「部分一致」なのか、コレクションの「完全一致」なのかを明確に区別する。

これらのテクニックを適切に使い分けることで、バグが少なくメンテナンス性の高いC#プログラムを記述できるようになります。

まずは基本のContainsから使いこなし、徐々にLINQや正規表現を組み合わせた高度な判定に挑戦してみてください。

基本操作

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!