[C#] 正規表現の名前付きグループの使い方 – Math.Groups()
C#で正規表現を使用する際、名前付きグループを使うことで、マッチした部分文字列にラベルを付けてアクセスできます。
名前付きグループは、正規表現パターン内で (?<name>...)
の形式で定義します。
マッチ結果は Match.Groups["name"]
で取得可能です。
例えば、(?<year>\d{4})
というパターンを使うと、Groups["year"]
で年の部分を取得できます。
これにより、複数のグループを扱う際にインデックスではなく名前でアクセスでき、コードの可読性が向上します。
- 名前付きグループの基本的な使い方
- Match.Groupsの詳細な解説
- 名前付きグループの応用例
- データ抽出の実践的な方法
- 正規表現の可読性向上の重要性
名前付きグループの基本的な使い方
C#の正規表現において、名前付きグループは特定の部分を簡単に参照できる便利な機能です。
これにより、複雑なパターンから特定の情報を抽出する際に、コードがより読みやすくなります。
以下では、名前付きグループの基本的な使い方を解説します。
名前付きグループの構文
名前付きグループは、正規表現の中で(?<名前>パターン)
という形式で定義します。
ここで「名前」はグループに付ける名前で、「パターン」はマッチさせたい文字列のパターンです。
以下はその構文の例です。
string pattern = @"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})";
この例では、年、月、日をそれぞれ名前付きグループとして定義しています。
Match.Groupsの使い方
Match.Groups
は、正規表現のマッチ結果を格納するコレクションです。
名前付きグループを使用することで、特定のグループに簡単にアクセスできます。
以下はその使い方の例です。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "2023-10-05";
string pattern = @"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
// 年を取得
string year = match.Groups["year"].Value;
// 月を取得
string month = match.Groups["month"].Value;
// 日を取得
string day = match.Groups["day"].Value;
Console.WriteLine($"年: {year}, 月: {month}, 日: {day}");
}
}
}
年: 2023, 月: 10, 日: 05
このコードでは、日付の文字列から年、月、日を抽出し、それぞれの値を表示しています。
名前付きグループの例:日付の抽出
日付の抽出において、名前付きグループを使用することで、特定の部分を簡単に取得できます。
以下はその具体例です。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "今日は2023-10-05です。";
string pattern = @"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
string year = match.Groups["year"].Value;
string month = match.Groups["month"].Value;
string day = match.Groups["day"].Value;
Console.WriteLine($"抽出した日付: {year}年{month}月{day}日");
}
}
}
抽出した日付: 2023年10月05日
この例では、文章中の日付を抽出し、フォーマットを整えて表示しています。
名前付きグループの例:メールアドレスの抽出
メールアドレスの抽出にも名前付きグループが役立ちます。
以下はその例です。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "私のメールアドレスはexample@example.comです。";
string pattern = @"(?<username>[\w.-]+)@(?<domain>[\w.-]+)";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
string username = match.Groups["username"].Value;
string domain = match.Groups["domain"].Value;
Console.WriteLine($"ユーザー名: {username}, ドメイン: {domain}");
}
}
}
ユーザー名: example, ドメイン: example.com
このコードでは、メールアドレスからユーザー名とドメインを抽出し、それぞれの値を表示しています。
Match.Groupsの詳細
Match.Groups
は、正規表現のマッチ結果を格納するコレクションであり、マッチした文字列の各部分にアクセスするための重要な機能です。
ここでは、Match.Groups
の詳細について解説します。
Match.Groupsとは
Match.Groups
は、正規表現によってマッチした結果を保持するGroupCollection
オブジェクトです。
このコレクションには、全体のマッチ結果と、名前付きグループやインデックスで指定されたグループが含まれています。
Match.Groups
を使用することで、マッチした各部分に簡単にアクセスできます。
Groupsのインデックスアクセスと名前付きアクセスの違い
Groups
コレクションには、インデックスアクセスと名前付きアクセスの2つの方法があります。
インデックスアクセスは、グループの順序に基づいてアクセスする方法で、名前付きアクセスは、グループに付けた名前を使用してアクセスする方法です。
以下にその違いを示します。
アクセス方法 | 説明 | 例 |
---|---|---|
インデックスアクセス | グループの順序でアクセス | match.Groups[0] (全体のマッチ) |
名前付きアクセス | グループに付けた名前でアクセス | match.Groups["year"] |
Groupsのプロパティとメソッド
Groups
コレクションには、いくつかのプロパティとメソッドがあります。
主なものを以下に示します。
プロパティ/メソッド | 説明 |
---|---|
Count | マッチしたグループの数を取得 |
Item | 指定したインデックスまたは名前のグループを取得 |
GetEnumerator | グループコレクションを列挙するためのメソッド |
Group.Successの使い方
Group.Success
プロパティは、特定のグループがマッチしたかどうかを示すブール値を返します。
これを使用することで、特定のグループが成功裏にマッチしたかを確認できます。
以下はその使用例です。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "2023-10-05";
string pattern = @"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
if (match.Groups["year"].Success)
{
Console.WriteLine("年がマッチしました。");
}
}
}
}
年がマッチしました。
このコードでは、年のグループがマッチしたかどうかを確認し、結果を表示しています。
Group.Valueの使い方
Group.Value
プロパティは、マッチしたグループの文字列を取得します。
これを使用することで、特定のグループの値を簡単に取得できます。
以下はその使用例です。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "2023-10-05";
string pattern = @"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
string year = match.Groups["year"].Value;
Console.WriteLine($"抽出した年: {year}");
}
}
}
抽出した年: 2023
このコードでは、年のグループから値を取得し、表示しています。
Group.Value
を使用することで、マッチした内容を簡単に取得できます。
名前付きグループの応用
名前付きグループは、正規表現を使ったデータ処理において非常に強力なツールです。
ここでは、名前付きグループの応用例をいくつか紹介します。
複数の名前付きグループを使う
複数の名前付きグループを使用することで、複雑なデータ構造から情報を効率的に抽出できます。
以下は、複数の名前付きグループを使った例です。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "2023年10月05日 12時30分";
string pattern = @"(?<year>\d{4})年(?<month>\d{2})月(?<day>\d{2})日 (?<hour>\d{2})時(?<minute>\d{2})分";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
string year = match.Groups["year"].Value;
string month = match.Groups["month"].Value;
string day = match.Groups["day"].Value;
string hour = match.Groups["hour"].Value;
string minute = match.Groups["minute"].Value;
Console.WriteLine($"抽出した日時: {year}年{month}月{day}日 {hour}時{minute}分");
}
}
}
抽出した日時: 2023年10月05日 12時30分
この例では、年、月、日、時、分をそれぞれ名前付きグループとして抽出しています。
名前付きグループと条件分岐
名前付きグループを使うことで、条件分岐を簡単に実装できます。
以下は、特定の条件に基づいて処理を分岐させる例です。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "2023-10-05 12:30:00";
string pattern = @"(?<date>\d{4}-\d{2}-\d{2}) (?<time>\d{2}:\d{2}:\d{2})";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
string date = match.Groups["date"].Value;
string time = match.Groups["time"].Value;
if (time.StartsWith("12"))
{
Console.WriteLine($"日付: {date}, 時間: 午後{time}");
}
else
{
Console.WriteLine($"日付: {date}, 時間: 午前{time}");
}
}
}
}
日付: 2023-10-05, 時間: 午後12:30:00
このコードでは、時間が12時で始まるかどうかで、午前か午後かを判断しています。
名前付きグループとループ処理
名前付きグループを使って、複数のマッチをループ処理することも可能です。
以下はその例です。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "2023-10-05, 2023-10-06, 2023-10-07";
string pattern = @"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})";
MatchCollection matches = Regex.Matches(input, pattern);
foreach (Match match in matches)
{
string year = match.Groups["year"].Value;
string month = match.Groups["month"].Value;
string day = match.Groups["day"].Value;
Console.WriteLine($"抽出した日付: {year}年{month}月{day}日");
}
}
}
抽出した日付: 2023年10月05日
抽出した日付: 2023年10月06日
抽出した日付: 2023年10月07日
この例では、カンマ区切りの日付をすべて抽出し、ループで表示しています。
名前付きグループを使ったデータの整形
名前付きグループを使用して、データを整形することもできます。
以下は、データを特定のフォーマットに整形する例です。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "2023-10-05 12:30:00";
string pattern = @"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) (?<hour>\d{2}):(?<minute>\d{2}):(?<second>\d{2})";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
string formattedDate = $"{match.Groups["year"].Value}/{match.Groups["month"].Value}/{match.Groups["day"].Value} {match.Groups["hour"].Value}:{match.Groups["minute"].Value}";
Console.WriteLine($"整形した日付: {formattedDate}");
}
}
}
整形した日付: 2023/10/05 12:30
このコードでは、日付と時間を特定のフォーマットに整形して表示しています。
名前付きグループを使ったログ解析
名前付きグループは、ログファイルの解析にも役立ちます。
以下は、ログから特定の情報を抽出する例です。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string log = "2023-10-05 12:30:00 ERROR: データベース接続失敗";
string pattern = @"(?<date>\d{4}-\d{2}-\d{2}) (?<time>\d{2}:\d{2}:\d{2}) (?<level>\w+): (?<message>.+)";
Match match = Regex.Match(log, pattern);
if (match.Success)
{
string date = match.Groups["date"].Value;
string time = match.Groups["time"].Value;
string level = match.Groups["level"].Value;
string message = match.Groups["message"].Value;
Console.WriteLine($"ログ情報: 日付={date}, 時間={time}, レベル={level}, メッセージ={message}");
}
}
}
ログ情報: 日付=2023-10-05, 時間=12:30:00, レベル=ERROR, メッセージ=データベース接続失敗
この例では、ログエントリから日付、時間、レベル、メッセージを抽出し、表示しています。
名前付きグループを使用することで、ログ解析が簡単になります。
実践例:名前付きグループを使ったデータ抽出
名前付きグループを使用することで、さまざまな形式のデータから特定の情報を効率的に抽出できます。
以下では、具体的な実践例をいくつか紹介します。
電話番号の抽出
電話番号の形式を正規表現で定義し、名前付きグループを使って抽出する例です。
日本の電話番号形式(市外局番、番号)を考慮しています。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "私の電話番号は03-1234-5678です。";
string pattern = @"(?<areaCode>\d{2,5})-(?<number1>\d{1,4})-(?<number2>\d{4})";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
string areaCode = match.Groups["areaCode"].Value;
string number1 = match.Groups["number1"].Value;
string number2 = match.Groups["number2"].Value;
Console.WriteLine($"市外局番: {areaCode}, 番号: {number1}-{number2}");
}
}
}
市外局番: 03, 番号: 1234-5678
この例では、電話番号から市外局番と番号を抽出しています。
URLのパース
URLからスキーム、ホスト、パスを抽出する例です。
名前付きグループを使って、各部分を簡単に取得できます。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "https://www.example.com/path/to/resource?query=123";
string pattern = @"(?<scheme>https?)://(?<host>[\w.-]+)/(?<path>.+)";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
string scheme = match.Groups["scheme"].Value;
string host = match.Groups["host"].Value;
string path = match.Groups["path"].Value;
Console.WriteLine($"スキーム: {scheme}, ホスト: {host}, パス: {path}");
}
}
}
スキーム: https, ホスト: www.example.com, パス: path/to/resource?query=123
このコードでは、URLからスキーム、ホスト、パスを抽出しています。
JSON形式のデータから特定の値を抽出
JSON形式のデータから特定のキーの値を抽出する例です。
正規表現を使って、名前付きグループで値を取得します。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "{\"name\":\"山田太郎\",\"age\":30}";
string pattern = @"\""name\"":\""(?<name>[^\\""]+)\"",";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
string name = match.Groups["name"].Value;
Console.WriteLine($"名前: {name}");
}
}
}
名前: 山田太郎
この例では、JSONデータから name
キーの値を抽出しています。
HTMLタグの解析
HTMLから特定のタグの内容を抽出する例です。
名前付きグループを使って、タグ名と内容を取得します。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "<div>こんにちは</div><p>世界</p>";
string pattern = @"<(?<tag>\w+)>(?<content>.*?)</\k<tag>>";
MatchCollection matches = Regex.Matches(input, pattern);
foreach (Match match in matches)
{
string tag = match.Groups["tag"].Value;
string content = match.Groups["content"].Value;
Console.WriteLine($"タグ: {tag}, 内容: {content}");
}
}
}
タグ: div, 内容: こんにちは
タグ: p, 内容: 世界
このコードでは、HTMLからタグ名とその内容を抽出しています。
CSVデータの解析
CSV形式のデータから特定の列を抽出する例です。
名前付きグループを使って、各列の値を取得します。
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "山田太郎,30,東京\n鈴木一郎,25,大阪";
string pattern = @"(?<name>[^,]+),(?<age>\d+),(?<city>[^,\n]+)";
MatchCollection matches = Regex.Matches(input, pattern);
foreach (Match match in matches)
{
string name = match.Groups["name"].Value;
string age = match.Groups["age"].Value;
string city = match.Groups["city"].Value;
Console.WriteLine($"名前: {name}, 年齢: {age}, 都市: {city}");
}
}
}
名前: 山田太郎, 年齢: 30, 都市: 東京
名前: 鈴木一郎, 年齢: 25, 都市: 大阪
この例では、CSVデータから名前、年齢、都市を抽出しています。
名前付きグループを使用することで、データの解析が簡単になります。
よくある質問
まとめ
この記事では、C#における正規表現の名前付きグループの使い方や応用例について詳しく解説しました。
名前付きグループを活用することで、複雑なデータから特定の情報を効率的に抽出できるため、プログラムの可読性や保守性が向上します。
今後は、実際のプロジェクトやデータ処理の場面で、名前付きグループを積極的に活用してみてください。