[C#] 正規表現のキャプチャグループの使い方を解説

C#で正規表現のキャプチャグループを使用するには、System.Text.RegularExpressions名前空間のRegexクラスを利用します。

キャプチャグループは、正規表現パターン内で括弧()を使って定義します。

マッチした部分文字列は、MatchオブジェクトのGroupsプロパティで取得できます。

例えば、Regex.Match("abc123", @"(\w+)(\d+)")では、(\w+)が最初のグループ、(\d+)が2番目のグループとしてキャプチャされます。

この記事でわかること
  • キャプチャグループの基本的な使い方
  • ネストされたキャプチャグループの活用法
  • 名前付きキャプチャグループの利点
  • 正規表現を用いた具体的な例
  • パフォーマンス最適化のポイント

目次から探す

キャプチャグループの基本

キャプチャグループは、正規表現において特定の部分を抽出するための機能です。

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

キャプチャグループを使うことで、マッチした文字列の中から特定の部分を簡単に取得できます。

キャプチャグループは、丸括弧 () を使って定義します。

例えば、正規表現 (\d{3})-(\d{4}) は、3桁の数字と4桁の数字をハイフンで区切った形式をマッチさせます。

この場合、最初のグループは市外局番、2番目のグループは電話番号の残りの部分をキャプチャします。

キャプチャグループは、番号付きキャプチャグループと名前付きキャプチャグループの2種類があります。

番号付きキャプチャグループは、マッチした順に番号が付けられ、名前付きキャプチャグループは、特定の名前を付けてアクセスすることができます。

これにより、コードの可読性が向上し、特定のデータを簡単に取得できるようになります。

C#でのキャプチャグループの使い方

Regexクラスの基本

C#で正規表現を扱うためには、System.Text.RegularExpressions名前空間に含まれるRegexクラスを使用します。

このクラスは、正規表現のパターンを定義し、文字列に対してマッチングを行うためのメソッドを提供します。

Regexクラスのインスタンスを作成する際には、正規表現のパターンをコンストラクタに渡します。

using System.Text.RegularExpressions;
Regex regex = new Regex(@"(\d{3})-(\d{4})");

MatchオブジェクトとGroupsプロパティ

RegexクラスMatchメソッドを使用すると、指定した文字列に対して正規表現を適用し、マッチした結果をMatchオブジェクトとして取得できます。

このオブジェクトには、マッチした文字列やキャプチャグループの情報が含まれています。

特に、Groupsプロパティを使用することで、各キャプチャグループにアクセスできます。

using System;
using System.Text.RegularExpressions;
Match match = regex.Match("123-4567");
if (match.Success)
{
    string areaCode = match.Groups[1].Value; // 123
    string number = match.Groups[2].Value;    // 4567
}

キャプチャグループの取得方法

キャプチャグループは、MatchオブジェクトのGroupsプロパティを通じて取得できます。

Groupsプロパティは、0番目のインデックスが全体のマッチを表し、1番目以降のインデックスが各キャプチャグループを表します。

以下のコードは、キャプチャグループを取得する方法を示しています。

using System;
using System.Text.RegularExpressions;
string input = "電話番号は123-4567です。";
Match match = regex.Match(input);
if (match.Success)
{
    string fullMatch = match.Groups[0].Value; // 電話番号は123-4567です。
    string areaCode = match.Groups[1].Value;  // 123
    string number = match.Groups[2].Value;     // 4567
}

名前付きキャプチャグループの取得方法

名前付きキャプチャグループを使用すると、グループに名前を付けてアクセスすることができます。

これにより、コードの可読性が向上します。

名前付きキャプチャグループは、(?<name>...)の形式で定義します。

以下の例では、名前付きキャプチャグループを使用して電話番号を抽出しています。

using System;
using System.Text.RegularExpressions;
Regex regex = new Regex(@"(?<areaCode>\d{3})-(?<number>\d{4})");
Match match = regex.Match("電話番号は123-4567です。");
if (match.Success)
{
    string areaCode = match.Groups["areaCode"].Value; // 123
    string number = match.Groups["number"].Value;      // 4567
}

キャプチャグループの例:文字列の分割

キャプチャグループを使用して、特定の形式の文字列を分割することができます。

例えば、日付の形式 YYYY/MM/DD を分割する場合、以下のようにキャプチャグループを使用します。

using System;
using System.Text.RegularExpressions;
Regex regex = new Regex(@"(?<year>\d{4})/(?<month>\d{2})/(?<day>\d{2})");
Match match = regex.Match("2023/10/01");
if (match.Success)
{
    string year = match.Groups["year"].Value;   // 2023
    string month = match.Groups["month"].Value; // 10
    string day = match.Groups["day"].Value;     // 01
}

キャプチャグループの例:特定のパターン抽出

特定のパターンを抽出するためにキャプチャグループを使用することもできます。

例えば、メールアドレスからユーザー名とドメインを抽出する場合、以下のように記述します。

using System;
using System.Text.RegularExpressions;
Regex regex = new Regex(@"(?<username>[^@]+)@(?<domain>.+)");
Match match = regex.Match("user@example.com");
if (match.Success)
{
    string username = match.Groups["username"].Value; // user
    string domain = match.Groups["domain"].Value;     // example.com
}

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

ネストされたキャプチャグループ

ネストされたキャプチャグループを使用すると、複雑なパターンをより細かく分解して抽出することができます。

例えば、電話番号の形式 (123) 456-7890 を処理する場合、以下のようにネストされたキャプチャグループを使用します。

using System;
using System.Text.RegularExpressions;
Regex regex = new Regex(@"\((?<areaCode>\d{3})\) (?<number>\d{3})-(?<extension>\d{4})");
Match match = regex.Match("(123) 456-7890");
if (match.Success)
{
    string areaCode = match.Groups["areaCode"].Value;   // 123
    string number = match.Groups["number"].Value;        // 456
    string extension = match.Groups["extension"].Value;  // 7890
}

キャプチャグループの再利用

キャプチャグループは、同じ正規表現内で再利用することができます。

これにより、同じパターンを繰り返し使用する際に便利です。

以下の例では、同じ数字のパターンを再利用しています。

using System;
using System.Text.RegularExpressions;
Regex regex = new Regex(@"(?<number>\d{3})-(?&number)-(?<number>\d{4})");
Match match = regex.Match("123-456-7890");
if (match.Success)
{
    string firstNumber = match.Groups["number"].Value; // 456
    string secondNumber = match.Groups["number"].Value; // 7890
}

非キャプチャグループの使い方

非キャプチャグループは、マッチングの際に特定の部分をグループ化するが、その結果を取得しない場合に使用します。

これにより、不要なキャプチャを避けることができます。

非キャプチャグループは、(?:...)の形式で定義します。

using System;
using System.Text.RegularExpressions;
Regex regex = new Regex(@"(?:\d{3})-(\d{4})");
Match match = regex.Match("123-4567");
if (match.Success)
{
    string number = match.Groups[1].Value; // 4567
}

キャプチャグループと条件付きパターン

条件付きパターンを使用すると、特定の条件に基づいてキャプチャグループを選択することができます。

以下の例では、電話番号が存在する場合にのみマッチするように条件を設定しています。

using System;
using System.Text.RegularExpressions;
Regex regex = new Regex(@"(?:(\d{3})-(\d{4}))|(\w+)");
Match match = regex.Match("123-4567");
if (match.Success)
{
    string number = match.Groups[1].Success ? match.Groups[1].Value : match.Groups[3].Value; // 123
}

キャプチャグループのパフォーマンス最適化

キャプチャグループを使用する際は、パフォーマンスに注意が必要です。

特に、複雑な正規表現や多くのキャプチャグループを使用する場合、処理速度が低下することがあります。

以下のポイントに留意して最適化を図ります。

  • 必要なキャプチャグループのみを使用する: 不要なキャプチャグループを避け、必要な部分だけをキャプチャします。
  • 非キャプチャグループを活用する: 結果を取得しない部分は非キャプチャグループを使用して、パフォーマンスを向上させます。
  • 正規表現の簡素化: 複雑なパターンを簡素化し、マッチングの効率を高めます。

これらの最適化を行うことで、正規表現のパフォーマンスを向上させることができます。

実践例:キャプチャグループを使った具体的なシナリオ

メールアドレスの抽出

メールアドレスを抽出するためには、正規表現を使用してユーザー名とドメインをキャプチャします。

以下の例では、メールアドレスからそれぞれの部分を抽出しています。

using System;
using System.Text.RegularExpressions;
class Program
{
    static void Main()
    {
        string input = "私のメールアドレスは user@example.com です。";
        Regex regex = new Regex(@"(?<username>[^@]+)@(?<domain>.+)");
        Match match = regex.Match(input);
        
        if (match.Success)
        {
            string username = match.Groups["username"].Value; // user
            string domain = match.Groups["domain"].Value;     // example.com
            Console.WriteLine($"ユーザー名: {username}, ドメイン: {domain}");
        }
    }
}
ユーザー名: user, ドメイン: example.com

日付フォーマットの変換

日付の形式を変換する際にもキャプチャグループが役立ちます。

以下の例では、日付の形式 YYYY/MM/DDDD-MM-YYYY に変換しています。

using System;
using System.Text.RegularExpressions;
class Program
{
    static void Main()
    {
        string input = "日付は2023/10/01です。";
        Regex regex = new Regex(@"(?<year>\d{4})/(?<month>\d{2})/(?<day>\d{2})");
        Match match = regex.Match(input);
        
        if (match.Success)
        {
            string formattedDate = $"{match.Groups["day"].Value}-{match.Groups["month"].Value}-{match.Groups["year"].Value}";
            Console.WriteLine($"変換後の日付: {formattedDate}");
        }
    }
}
変換後の日付: 01-10-2023

URLのパラメータ解析

URLからクエリパラメータを抽出するためにキャプチャグループを使用することができます。

以下の例では、URLから特定のパラメータを取得しています。

using System;
using System.Text.RegularExpressions;
class Program
{
    static void Main()
    {
        string input = "https://example.com/page?name=John&age=30";
        Regex regex = new Regex(@"[?&](?<key>[^=]+)=(?<value>[^&]+)");
        MatchCollection matches = regex.Matches(input);
        
        foreach (Match match in matches)
        {
            string key = match.Groups["key"].Value;
            string value = match.Groups["value"].Value;
            Console.WriteLine($"キー: {key}, 値: {value}");
        }
    }
}
キー: name, 値: John
キー: age, 値: 30

HTMLタグの抽出

HTMLから特定のタグを抽出する際にもキャプチャグループが役立ちます。

以下の例では、HTMLの<a>タグからリンク先のURLとテキストを抽出しています。

using System;
using System.Text.RegularExpressions;
class Program
{
    static void Main()
    {
        string input = "<a href=\"https://example.com\">Example</a>";
        Regex regex = new Regex(@"<a href=""(?<url>[^""]+)"">(?<text>[^<]+)</a>");
        Match match = regex.Match(input);
        
        if (match.Success)
        {
            string url = match.Groups["url"].Value;   // https://example.com
            string text = match.Groups["text"].Value; // Example
            Console.WriteLine($"URL: {url}, テキスト: {text}");
        }
    }
}
URL: https://example.com, テキスト: Example

ログファイルからのデータ抽出

ログファイルから特定の情報を抽出するためにもキャプチャグループを使用できます。

以下の例では、ログエントリから日付とメッセージを抽出しています。

using System;
using System.Text.RegularExpressions;
class Program
{
    static void Main()
    {
        string input = "2023-10-01 12:00:00 INFO: プログラムが開始されました。";
        Regex regex = new Regex(@"(?<date>\d{4}-\d{2}-\d{2}) (?<time>\d{2}:\d{2}:\d{2}) (?<level>\w+): (?<message>.+)");
        Match match = regex.Match(input);
        
        if (match.Success)
        {
            string date = match.Groups["date"].Value;       // 2023-10-01
            string time = match.Groups["time"].Value;       // 12:00:00
            string level = match.Groups["level"].Value;     // INFO
            string message = match.Groups["message"].Value; // プログラムが開始されました。
            Console.WriteLine($"日付: {date}, 時間: {time}, レベル: {level}, メッセージ: {message}");
        }
    }
}
日付: 2023-10-01, 時間: 12:00:00, レベル: INFO, メッセージ: プログラムが開始されました。

よくある質問

キャプチャグループの番号はどうやって決まる?

キャプチャグループの番号は、正規表現内でのグループの出現順に基づいて決まります。

最初のキャプチャグループは1番、次のキャプチャグループは2番といった具合に、左から右へと番号が付けられます。

全体のマッチは0番目のグループとして扱われます。

例えば、正規表現(\d{3})-(\d{4})では、(\d{3})が1番、(\d{4})が2番のキャプチャグループになります。

名前付きキャプチャグループと番号付きキャプチャグループの違いは?

名前付きキャプチャグループは、特定の名前を付けてアクセスできるキャプチャグループです。

これに対して、番号付きキャプチャグループは、出現順に番号でアクセスします。

名前付きキャプチャグループは、可読性が高く、特に複雑な正規表現を扱う際に便利です。

例えば、(?<username>[^@]+)のように定義すると、match.Groups["username"].Valueでアクセスできます。

一方、番号付きキャプチャグループは、match.Groups[1].Valueのように番号でアクセスします。

非キャプチャグループはどのような場合に使うべき?

非キャプチャグループは、マッチングの際に特定の部分をグループ化するが、その結果を取得しない場合に使用します。

これにより、不要なキャプチャを避け、パフォーマンスを向上させることができます。

例えば、特定のパターンをグループ化して条件を設定したいが、その部分の値を取得する必要がない場合に非キャプチャグループを使用します。

(?:...)の形式で定義し、マッチングの効率を高めることができます。

まとめ

この記事では、C#におけるキャプチャグループの基本的な使い方から応用例までを詳しく解説しました。

キャプチャグループを活用することで、正規表現を用いた文字列処理がより効率的かつ柔軟に行えるようになります。

今後は、実際のプロジェクトや日常のプログラミングにおいて、キャプチャグループを積極的に活用し、より複雑なデータ処理に挑戦してみてください。

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