閉じる

【C#】正規表現でOR(または)条件を指定する方法|複数一致や記法のまとめ

C#を用いたアプリケーション開発において、文字列のパターンマッチングは欠かせない要素です。

ユーザー入力のバリデーション、ログファイルの解析、テキストデータの抽出など、さまざまな場面で「正規表現」が活用されています。

その中でも「AまたはB」というOR条件(選択)の指定は、最も頻繁に利用されるテクニックの一つです。

本記事では、C#の「System.Text.RegularExpressions」名前空間を使用した正規表現において、OR条件を効果的に使いこなす方法を、基礎から応用、そしてパフォーマンスの最適化まで徹底的に解説します。

正規表現におけるOR条件の基本記法

正規表現で「または」という条件を表現するには、パイプ記号 | を使用します。

これはプログラミング言語における論理和(OR)と同様の役割を果たします。

例えば、Apple|Orange というパターンは、「Apple」または「Orange」のいずれかの文字列に一致することを意味します。

正規表現エンジンは、指定されたパターンを左から右へと評価していきます。

Apple|Orange の場合、まず「Apple」に適合するかを試し、適合しなければ次に「Orange」を試します。

このように、複数の候補を並列して定義できるのがOR条件の最大の特徴です。

C#でこの基本形を利用する場合、最もシンプルなコードは以下のようになります。

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

public class Program
{
    public static void Main()
    {
        string input = "I like Apple.";
        string pattern = "Apple|Orange";

        if (Regex.IsMatch(input, pattern))
        {
            Console.WriteLine("一致しました。");
        }
    }
}

このコードでは、Regex.IsMatch メソッドを使用して、入力文字列に「Apple」または「Orange」が含まれているかを確認しています。

複数のOR条件を連結する

OR条件は2つだけでなく、3つ以上の候補を連結することも可能です。

例えば、Red|Blue|Green|Yellow と記述すれば、4つの色のいずれかに一致させることができます。

候補が増えても基本的な動作原理は同じですが、候補の順番がマッチング結果に影響を与える場合がある点には注意が必要です。

グループ化を用いたOR条件の限定

単純に | を使うだけでは、正規表現全体がOR条件の対象になってしまいます。

特定の単語の一部だけをOR条件にしたい場合は、丸括弧 () を使用したグループ化が必要不可欠です。

例えば、「Monday Night」または「Tuesday Night」に一致させたい場合、Monday|Tuesday Night と書くと、意図に反して「Monday」または「Tuesday Night」という解釈になってしまいます。

これを防ぐために、(Monday|Tuesday) Night と記述します。

キャプチャグループの活用

丸括弧 () は、単に範囲を限定するだけでなく、一致した部分を「キャプチャ」して後で利用できるようにする機能も持っています。

C#
string input = "Today is Tuesday Night.";
string pattern = @"(Monday|Tuesday) Night";

Match match = Regex.Match(input, pattern);
if (match.Success)
{
    // グループ1((Monday|Tuesday)の部分)に一致した値を取得
    Console.WriteLine("Day: " + match.Groups[1].Value); // 出力: Tuesday
}

このように、OR条件で一致した方の値を個別に抽出したい場合に非常に便利です。

非キャプチャグループによる最適化

グループ化は便利ですが、キャプチャ(一致した値の保持)はメモリやCPUリソースを消費します。

単に範囲を限定したいだけで、後でその値を取り出す必要がない場合は、非キャプチャグループ (?:…) を使用するのがベストプラクティスです。

記法名称特徴
(A|B)キャプチャグループAまたはBに一致し、その結果をメモリに保存する
(?:A|B)非キャプチャグループAまたはBに一致するが、結果は保存しない(高速)

大量のテキストデータを処理する場合や、ループ内で頻繁に正規表現を実行する場合は、この (?:...) を積極的に活用することで、アプリケーションのパフォーマンス向上が期待できます。

実践的な活用シーンとサンプルコード

C#開発でよく遭遇するOR条件の具体的なユースケースを見ていきましょう。

ファイル拡張子の判定

特定の種類のファイルのみを処理したい場合、OR条件が非常に有効です。

C#
string[] files = { "image.png", "document.pdf", "photo.jpg", "script.py" };
// png, jpg, jpeg のいずれかに一致(大文字小文字を区別しない)
string pattern = @"\.(?:png|jpg|jpeg)$";

foreach (var file in files)
{
    if (Regex.IsMatch(file, pattern, RegexOptions.IgnoreCase))
    {
        Console.WriteLine($"対象ファイル: {file}");
    }
}

複数のURLスキームのチェック

http または https から始まるURLを検証する例です。

C#
string url = "https://example.com";
// http または https で始まり、その後に :// が続く
string pattern = @"^https?://"; 
// ※ 's?' も一種のOR(sがあるかないか)だが、
// 明示的に書くなら @"^(?:http|https)://" となる

文字クラスを用いたOR(1文字の場合)

もしOR条件の対象が「1文字」であれば、| よりも 文字クラス [] を使う方が効率的です。

例えば、a|b|c ではなく [abc] と記述します。

これは「a, b, cのいずれか1文字」という意味になり、正規表現エンジンの内部処理が最適化されます。

C# での正規表現のパフォーマンスと最新機能

C# 11以降、.NET 7や.NET 8では正規表現のパフォーマンスが飛躍的に向上しています。

特に注目すべきは、「Regex Source Generator」の導入です。

これまでの Regex クラスは、実行時にパターンを解析していましたが、Source Generator を使用すると、コンパイル時に正規表現の解析コードを生成します。

これにより、起動時間の短縮と実行速度の大幅な向上が実現します。

Regex Source Generator の使用例

C#
using System.Text.RegularExpressions;

public partial class MyParser
{
    // コンパイル時に正規表現エンジンを生成
    [GeneratedRegex(@"Apple|Orange", RegexOptions.IgnoreCase)]
    private static partial Regex FoodRegex();

    public void Parse(string text)
    {
        if (FoodRegex().IsMatch(text))
        {
            // 処理
        }
    }
}

OR条件が複雑になればなるほど、バックトラッキング(マッチングのやり直し)が発生しやすくなり、パフォーマンスが低下します。

Source Generator を利用することで、このような複雑なパターンも極めて効率的なステートマシンとして実装されるため、積極的に導入を検討すべきです。

よくある落とし穴と注意点

正規表現のOR条件を使用する際には、いくつか注意すべき「罠」があります。

1. 候補の順番による「部分一致」の罠

正規表現のORは、左側から順に評価され、最初に一致したものが見つかった時点で確定します(最長一致の原則が適用されるのは、同一の分岐内のみです)。

例えば、Microsoft|Microsoft Office というパターンに対して、「Microsoft Office」という入力を与えると、先に Microsoft に一致してしまい、後半の Office 部分が無視されることがあります。

この場合は、Microsoft Office|Microsoft のように、より具体的な(長い)パターンを先に記述するのが鉄則です。

2. 大文字・小文字の区別

デフォルトでは、OR条件内の文字列は大文字と小文字を厳密に区別します。

apple|Orange は「apple」には一致しますが、「Apple」には一致しません。

これを回避するには、RegexOptions.IgnoreCase を指定するか、パターン内で (?i)apple|orange のようにインラインオプションを使用します。

3. メタ文字のエスケープ

OR条件の候補の中に、.*? などの正規表現記号を含める場合は、必ずバックスラッシュ \ でエスケープしてください。

例えば、1.5 または 2.5 に一致させたい場合は、1.5|2.5 と記述します。

まとめ

C#における正規表現のOR条件は、パイプ記号 | とグループ化 () を組み合わせることで、非常に柔軟なパターンマッチングを実現します。

  • 基本的な「または」は A|B
  • 範囲を限定するには (A|B)
  • パフォーマンスを重視するなら非キャプチャグループ (?:A|B)
  • 1文字のORなら文字クラス [ABC]
  • モダンな.NET開発では GeneratedRegex を活用

これらのテクニックを適切に使い分けることで、可読性が高く、かつ高速に動作するコードを記述できるようになります。

正規表現は一見複雑ですが、OR条件という強力な武器をマスターすることは、C#プログラミングの効率を大きく引き上げる第一歩となるでしょう。

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

URLをコピーしました!