C#のMatchとは?Regex.Matchの使い方・一致判定・複数抽出を初心者向けに解説

はじめに

C#で文字列を扱っていると、「特定の文字列が含まれているか調べたい」「メールアドレスの形式か判定したい」「文章の中から数字だけ取り出したい」といった場面がよくあります。

そのようなときに便利なのが、正規表現を使って文字列を検索できるRegex.Matchです。

Regex.Matchを使うと、文字列の中から正規表現パターンに一致する部分を探し、一致した文字列、開始位置、文字数、グループ化した値などを取得できます。

この記事では、C#のMatchとは何か、Regex.Matchの基本的な使い方、一致判定、文字列の抽出、複数抽出、Regex.MatchesRegex.IsMatchとの違いまで、初心者にもわかりやすく解説します。

1. C#のMatchとは?Regex.Matchでできること

C#におけるMatchは、正規表現による検索結果を表すオブジェクトです。

正規表現を使って文字列を検索すると、「一致したかどうか」「どの文字列が一致したか」「文字列のどの位置で一致したか」といった情報が必要になります。Matchは、それらの情報をまとめて持っています。

1-1. Matchは「正規表現に一致した結果」を表すオブジェクト

Matchは、System.Text.RegularExpressions名前空間にあるクラスです。

たとえば、次のような文字列があるとします。

C#
string text = "価格は1200円です";

この文字列から数字を取り出したい場合、正規表現の\d+を使うと、1200に一致します。

C#
Match match = Regex.Match(text, @"\d+");

このとき、matchには「1200に一致した」という検索結果が入ります。

Matchオブジェクトを使うことで、次のような情報を取得できます。

C#
Console.WriteLine(match.Success); // True
Console.WriteLine(match.Value); // 1200
Console.WriteLine(match.Index); // 一致した開始位置
Console.WriteLine(match.Length); // 一致した文字数

1-2. Regex.Matchは文字列から最初に一致した部分を取得するメソッド

Regex.Matchは、指定した文字列の中から正規表現パターンに一致する部分を探し、最初に見つかった1件をMatchオブジェクトとして返すメソッドです。

C#
Match match = Regex.Match("abc123def456", @"\d+");

Console.WriteLine(match.Value);

実行結果は次のようになります。

123

文字列の中には123456という2つの数字がありますが、Regex.Matchが返すのは最初に一致した123だけです。

複数の一致を取得したい場合は、NextMatchまたはRegex.Matchesを使います。

1-3. 「一致判定」「値の取得」「位置の取得」「グループ抽出」に使える

Regex.Matchは、単に文字列を探すだけではありません。

主に次のような用途で使えます。

C#
string text = "商品ID: A-12345";
Match match = Regex.Match(text, @"A-\d+");

if (match.Success)
{
Console.WriteLine("一致しました");
Console.WriteLine(match.Value);
Console.WriteLine(match.Index);
Console.WriteLine(match.Length);
}

このコードでは、A-12345という形式の文字列を検索しています。

match.Successで一致判定を行い、match.Valueで一致した文字列を取得しています。さらに、IndexLengthを使えば、どこから何文字一致したのかも確認できます。

また、丸括弧を使ったキャプチャグループを利用すると、日付から年・月・日を分けて取り出すような処理もできます。

1-4. C#のpattern matchingやstring.Containsとの違い

C#には、Matchという言葉に関連して混同しやすい機能があります。

ひとつは、C#のpattern matchingです。

C#
object value = 123;

if (value is int number)
{
Console.WriteLine(number);
}

これは、オブジェクトの型や値のパターンを判定するC#の構文です。正規表現のRegex.Matchとは別物です。

もうひとつは、string.Containsです。

C#
string text = "Hello C#";

if (text.Contains("C#"))
{
Console.WriteLine("含まれています");
}

string.Containsは、単純に特定の文字列が含まれているかを調べるメソッドです。

一方、Regex.Matchは正規表現を使えるため、次のような柔軟な検索ができます。

C#
Regex.Match("abc123", @"\d+");

この例では、「数字が1文字以上続く部分」を検索できます。

単純な文字列検索ならContains、複雑なパターン検索ならRegex.Matchを使うと考えるとわかりやすいです。

2. Regex.Matchを使うための準備

Regex.Matchを使うには、正規表現関連のクラスが含まれている名前空間を読み込む必要があります。

2-1. System.Text.RegularExpressionsをusingする

C#でRegexMatchを使うには、ファイルの先頭に次のusingを追加します。

C#
using System.Text.RegularExpressions;

これにより、Regex.MatchMatchクラスをそのまま使えるようになります。

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

class Program
{
static void Main()
{
string text = "abc123";
Match match = Regex.Match(text, @"\d+");

Console.WriteLine(match.Value);
}
}

2-2. Regex.Matchの基本構文

Regex.Matchの基本構文は次のとおりです。

C#
Match match = Regex.Match(入力文字列, 正規表現パターン);

具体例は次のようになります。

C#
string text = "商品番号は12345です";
string pattern = @"\d+";

Match match = Regex.Match(text, pattern);

このコードでは、textの中から数字が1文字以上続く部分を検索しています。

2-3. 第1引数の入力文字列と第2引数の正規表現パターン

Regex.Matchの第1引数には検索対象の文字列を指定します。

C#
string text = "User ID: 789";

第2引数には正規表現パターンを指定します。

C#
string pattern = @"\d+";

この2つを組み合わせると、次のようになります。

C#
Match match = Regex.Match(text, pattern);

\d+は「数字が1文字以上続く部分」を意味します。

C#ではバックスラッシュを含む正規表現を書くことが多いため、@"\d+"のように@を付けた逐語的文字列リテラルを使うと読みやすくなります。

2-4. まずは数字を抽出する簡単なサンプル

最初に、文字列から数字を抽出する簡単な例を見てみましょう。

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

class Program
{
static void Main()
{
string text = "年齢は25歳です";
Match match = Regex.Match(text, @"\d+");

if (match.Success)
{
Console.WriteLine("見つかった数字: " + match.Value);
}
}
}

実行結果は次のようになります。

見つかった数字: 25

Regex.Matchで検索し、match.Successで一致したか確認してからmatch.Valueを表示しています。

3. Matchオブジェクトの主要プロパティ

Regex.Matchが返すMatchオブジェクトには、検索結果に関する便利なプロパティがあります。

特によく使うのは、SuccessValueIndexLengthです。

3-1. Successで一致したか判定する

Successは、正規表現に一致したかどうかを表すbool型のプロパティです。

C#
string text = "abc123";
Match match = Regex.Match(text, @"\d+");

if (match.Success)
{
Console.WriteLine("一致しました");
}
else
{
Console.WriteLine("一致しませんでした");
}

一致すればtrue、一致しなければfalseになります。

Regex.Matchを使うときは、Valueを使う前にSuccessを確認するのが基本です。

3-2. Valueで一致した文字列を取得する

Valueは、実際に一致した文字列を取得するプロパティです。

C#
string text = "注文番号: 5678";
Match match = Regex.Match(text, @"\d+");

if (match.Success)
{
Console.WriteLine(match.Value);
}

実行結果は次のようになります。

5678

Valueを使えば、文字列の中から見つかった部分だけを簡単に取り出せます。

3-3. Indexで一致した開始位置を取得する

Indexは、一致した文字列が入力文字列の何文字目から始まっているかを表します。

C#
string text = "abc123";
Match match = Regex.Match(text, @"\d+");

if (match.Success)
{
Console.WriteLine(match.Index);
}

実行結果は次のようになります。

3

C#の文字列の位置は0から数えるため、abc1231はインデックス3になります。

3-4. Lengthで一致した文字数を取得する

Lengthは、一致した文字列の長さを表します。

C#
string text = "abc12345def";
Match match = Regex.Match(text, @"\d+");

if (match.Success)
{
Console.WriteLine(match.Length);
}

実行結果は次のようになります。

5

この例では、12345の5文字が一致しています。

3-5. Emptyや失敗時のMatchの扱い

Regex.Matchは、一致しない場合でもnullを返しません。

一致しなかった場合は、SuccessfalseMatchオブジェクトが返されます。

C#
string text = "abcdef";
Match match = Regex.Match(text, @"\d+");

Console.WriteLine(match.Success);
Console.WriteLine(match.Value);

実行結果は次のようになります。

False

Valueは空文字列になります。

そのため、次のようにmatch == nullで判定するのではなく、match.Successで判定します。

C#
if (match.Success)
{
Console.WriteLine(match.Value);
}

4. Regex.Matchで一致判定する方法

Regex.Matchを使うと、入力文字列が特定のパターンに一致するかどうかを判定できます。

4-1. match.Successを使った基本的なif文

一致判定の基本は、match.Successを使ったif文です。

C#
string text = "abc123";
Match match = Regex.Match(text, @"\d+");

if (match.Success)
{
Console.WriteLine("数字が含まれています");
}
else
{
Console.WriteLine("数字は含まれていません");
}

この例では、文字列の中に数字が含まれているかを判定しています。

4-2. メールアドレス・電話番号・郵便番号の判定例

メールアドレスらしい形式か判定する例です。

C#
string email = "user@example.com";
string pattern = @"^[^@\s]+@[^@\s]+\.[^@\s]+$";

Match match = Regex.Match(email, pattern);

if (match.Success)
{
Console.WriteLine("メールアドレス形式です");
}

電話番号を判定する例です。

C#
string phone = "090-1234-5678";
string pattern = @"^\d{2,4}-\d{2,4}-\d{3,4}$";

Match match = Regex.Match(phone, pattern);

if (match.Success)
{
Console.WriteLine("電話番号形式です");
}

郵便番号を判定する例です。

C#
string postalCode = "123-4567";
string pattern = @"^\d{3}-\d{4}$";

Match match = Regex.Match(postalCode, pattern);

if (match.Success)
{
Console.WriteLine("郵便番号形式です");
}

^は文字列の先頭、$は文字列の末尾を意味します。

入力全体がパターンに一致しているかを判定したい場合は、^$を使うのがポイントです。

4-3. Regex.IsMatchとの違い

一致するかどうかだけを知りたい場合は、Regex.IsMatchも使えます。

C#
bool result = Regex.IsMatch("abc123", @"\d+");

Console.WriteLine(result);

実行結果は次のようになります。

True

Regex.IsMatchは、一致したかどうかをboolで返します。

一方、Regex.MatchMatchオブジェクトを返します。

C#
Match match = Regex.Match("abc123", @"\d+");

Regex.Matchでは、判定だけでなく、一致した文字列や位置なども取得できます。

4-4. 判定だけならIsMatch、値も使うならMatchを選ぶ

使い分けの目安はシンプルです。

一致したかどうかだけを知りたいならRegex.IsMatchを使います。

C#
if (Regex.IsMatch(input, @"^\d+$"))
{
Console.WriteLine("数字のみです");
}

一致した文字列を取得したいならRegex.Matchを使います。

C#
Match match = Regex.Match(input, @"\d+");

if (match.Success)
{
Console.WriteLine(match.Value);
}

判定だけならIsMatch、抽出もするならMatchと覚えておくとよいでしょう。

5. Regex.Matchで一致した文字列を抽出する方法

Regex.Matchの代表的な使い方は、文字列の中から特定のパターンに一致する部分を抽出することです。

5-1. 最初に一致した文字列をValueで取得する

一致した文字列は、match.Valueで取得できます。

C#
string text = "価格は980円です";
Match match = Regex.Match(text, @"\d+");

if (match.Success)
{
Console.WriteLine(match.Value);
}

実行結果は次のようになります。

980

5-2. 一致位置をIndexで確認する

一致した文字列がどこにあるかを確認したい場合は、Indexを使います。

C#
string text = "abc123def";
Match match = Regex.Match(text, @"\d+");

if (match.Success)
{
Console.WriteLine("値: " + match.Value);
Console.WriteLine("開始位置: " + match.Index);
}

実行結果は次のようになります。

値: 123
開始位置: 3

5-3. 一致しなかった場合の安全な書き方

一致しなかった場合、Valueは空文字列になります。

ただし、意図しない処理を避けるため、基本的にはSuccessを確認してからValueを使います。

C#
string text = "abcdef";
Match match = Regex.Match(text, @"\d+");

if (match.Success)
{
Console.WriteLine("見つかりました: " + match.Value);
}
else
{
Console.WriteLine("見つかりませんでした");
}

このように書くことで、一致しなかった場合も安全に処理できます。

5-4. 実践例:文章から数値・日付・URLを取り出す

文章から数値を取り出す例です。

C#
string text = "合計金額は3500円です";
Match match = Regex.Match(text, @"\d+");

if (match.Success)
{
Console.WriteLine(match.Value);
}

日付を取り出す例です。

C#
string text = "開催日は2026-06-19です";
Match match = Regex.Match(text, @"\d{4}-\d{2}-\d{2}");

if (match.Success)
{
Console.WriteLine(match.Value);
}

URLを取り出す例です。

C#
string text = "公式サイトはhttps://example.comです";
Match match = Regex.Match(text, @"https?://[^\s]+");

if (match.Success)
{
Console.WriteLine(match.Value);
}

実務では、ログ、入力フォーム、CSV、HTML、メール本文などから必要な値を取り出すときによく使います。

6. Groupsを使って一部の文字列を取り出す

Regex.Matchでは、一致した文字列全体だけでなく、その一部を取り出すこともできます。

そのために使うのがGroupsです。

6-1. 丸括弧でキャプチャグループを作る

正規表現の中で丸括弧()を使うと、キャプチャグループを作れます。

C#
string text = "商品コード: ABC-123";
Match match = Regex.Match(text, @"([A-Z]+)-(\d+)");

if (match.Success)
{
Console.WriteLine(match.Groups[1].Value);
Console.WriteLine(match.Groups[2].Value);
}

実行結果は次のようになります。

ABC
123

([A-Z]+)が英字部分、(\d+)が数字部分を表しています。

6-2. Groups[0]とGroups[1]以降の違い

Groups[0]には、一致した文字列全体が入ります。

Groups[1]以降には、丸括弧で囲んだキャプチャグループの値が順番に入ります。

C#
string text = "ABC-123";
Match match = Regex.Match(text, @"([A-Z]+)-(\d+)");

if (match.Success)
{
Console.WriteLine(match.Groups[0].Value);
Console.WriteLine(match.Groups[1].Value);
Console.WriteLine(match.Groups[2].Value);
}

実行結果は次のようになります。

ABC-123
ABC
123

Groups[0]は全体、Groups[1]以降は部分的な一致と覚えておきましょう。

6-3. 日付から年・月・日を分けて取得する例

日付文字列から年、月、日を分けて取得する例です。

C#
string text = "日付: 2026-06-19";
Match match = Regex.Match(text, @"(\d{4})-(\d{2})-(\d{2})");

if (match.Success)
{
string year = match.Groups[1].Value;
string month = match.Groups[2].Value;
string day = match.Groups[3].Value;

Console.WriteLine(year);
Console.WriteLine(month);
Console.WriteLine(day);
}

実行結果は次のようになります。

2026
06
19

このように、Groupsを使うと、ひとつの一致結果から複数の値を取り出せます。

6-4. 名前付きグループで可読性を上げる

グループ番号だけでなく、名前付きグループを使うこともできます。

C#
string text = "日付: 2026-06-19";
string pattern = @"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})";

Match match = Regex.Match(text, pattern);

if (match.Success)
{
Console.WriteLine(match.Groups["year"].Value);
Console.WriteLine(match.Groups["month"].Value);
Console.WriteLine(match.Groups["day"].Value);
}

名前付きグループを使うと、Groups[1]のような番号よりも意味がわかりやすくなります。

複雑な正規表現では、名前付きグループを使うと保守しやすくなります。

6-5. グループが一致しない場合の注意点

グループは、パターンによっては一致しないことがあります。

C#
string text = "商品: ABC";
string pattern = @"([A-Z]+)(-(\d+))?";

Match match = Regex.Match(text, pattern);

if (match.Success)
{
Console.WriteLine(match.Groups[1].Value);
Console.WriteLine(match.Groups[3].Success);
Console.WriteLine(match.Groups[3].Value);
}

この例では、数字部分が省略可能です。

Groups[3]が一致していない場合、Successfalseになり、Valueは空文字列になります。

グループの値を使うときも、必要に応じてGroups[n].Successを確認すると安全です。

7. 複数の一致を抽出する方法

Regex.Matchは最初の一致だけを返します。

文字列の中に複数の一致がある場合は、NextMatchまたはRegex.Matchesを使います。

7-1. Regex.Matchは最初の1件だけを返す

次の例を見てみましょう。

C#
string text = "apple 100 yen, banana 200 yen";
Match match = Regex.Match(text, @"\d+");

Console.WriteLine(match.Value);

実行結果は次のようになります。

100

100200の両方が文字列に含まれていますが、Regex.Matchで取得できるのは最初の100だけです。

7-2. NextMatchで次の一致を順番に取得する

NextMatchを使うと、次の一致を順番に取得できます。

C#
string text = "apple 100 yen, banana 200 yen";
Match match = Regex.Match(text, @"\d+");

while (match.Success)
{
Console.WriteLine(match.Value);
match = match.NextMatch();
}

実行結果は次のようになります。

100
200

NextMatchは、現在の一致の次にある一致結果を返します。

7-3. Regex.Matchesで一致したすべての結果を取得する

複数の一致をまとめて取得したい場合は、Regex.Matchesを使うのが一般的です。

C#
string text = "apple 100 yen, banana 200 yen";
MatchCollection matches = Regex.Matches(text, @"\d+");

foreach (Match match in matches)
{
Console.WriteLine(match.Value);
}

実行結果は次のようになります。

100
200

Regex.Matchesは、一致したすべての結果をMatchCollectionとして返します。

7-4. MatchCollectionをforeachで処理する

Regex.Matchesの戻り値であるMatchCollectionは、foreachで簡単に処理できます。

C#
string text = "ID: 101, ID: 202, ID: 303";
MatchCollection matches = Regex.Matches(text, @"\d+");

foreach (Match match in matches)
{
Console.WriteLine("ID: " + match.Value);
}

実行結果は次のようになります。

ID: 101
ID: 202
ID: 303

複数の数値、単語、URL、タグなどを抽出するときに便利です。

7-5. 複数抽出ではMatchとMatchesをどう使い分けるか

最初の1件だけ取得したい場合はRegex.Matchを使います。

C#
Match match = Regex.Match(text, pattern);

すべての一致を取得したい場合はRegex.Matchesを使います。

C#
MatchCollection matches = Regex.Matches(text, pattern);

NextMatchは、最初の一致から順番に処理したい場合に使えますが、初心者にはRegex.Matchesのほうが直感的でわかりやすいでしょう。

8. Regex.Matchのよく使う正規表現パターン

Regex.Matchを使いこなすには、基本的な正規表現パターンを覚えておくと便利です。

8-1. 数字に一致する\d+

\dは数字1文字に一致します。

\d+にすると、数字が1文字以上続く部分に一致します。

C#
Match match = Regex.Match("abc123def", @"\d+");

Console.WriteLine(match.Value);

実行結果は次のようになります。

123

8-2. 英字に一致する[a-zA-Z]+

英字に一致させたい場合は、[a-zA-Z]+を使います。

C#
Match match = Regex.Match("123abc456", @"[a-zA-Z]+");

Console.WriteLine(match.Value);

実行結果は次のようになります。

abc

[a-z]は小文字、[A-Z]は大文字を表します。

8-3. 任意の文字数に一致する.*

.は任意の1文字に一致します。

*は直前の文字が0回以上繰り返すことを表します。

つまり、.*は任意の文字が0文字以上続く部分に一致します。

C#
string text = "start hello end";
Match match = Regex.Match(text, @"start.*end");

Console.WriteLine(match.Value);

実行結果は次のようになります。

start hello end

ただし、.*は広く一致しすぎることがあります。必要以上に大きな範囲に一致しないよう注意が必要です。

8-4. 行頭・行末を表す^と$

^は文字列の先頭、$は文字列の末尾を表します。

C#
bool result = Regex.IsMatch("12345", @"^\d+$");

Console.WriteLine(result);

実行結果は次のようになります。

True

この例では、文字列全体が数字だけで構成されているかを判定しています。

^\d+$は「先頭から末尾まで数字が1文字以上続く」という意味です。

8-5. 空白文字に一致する\s

\sは空白文字に一致します。

スペース、タブ、改行などを対象にできます。

C#
string text = "Hello   World";
Match match = Regex.Match(text, @"\s+");

if (match.Success)
{
Console.WriteLine("空白が見つかりました");
}

\s+は、空白文字が1文字以上続く部分に一致します。

8-6. 文字をエスケープする方法

正規表現では、.+*?()[]などは特別な意味を持ちます。

これらの文字そのものに一致させたい場合は、バックスラッシュでエスケープします。

たとえば、ドット.そのものに一致させたい場合は次のように書きます。

C#
Match match = Regex.Match("file.txt", @"\.");

Console.WriteLine(match.Value);

実行結果は次のようになります。

.

C#では通常の文字列だとバックスラッシュをさらにエスケープする必要があります。

C#
Regex.Match("file.txt", "\\.");

逐語的文字列リテラルを使えば、次のように書けます。

C#
Regex.Match("file.txt", @"\.");

正規表現では@付きの文字列を使うと読みやすくなります。

9. Regex.Matchでよくあるエラー・つまずきポイント

Regex.Matchは便利ですが、初心者がつまずきやすいポイントもあります。

9-1. 正規表現パターンのバックスラッシュで失敗する

C#の文字列では、バックスラッシュ\はエスケープ文字として扱われます。

そのため、通常の文字列で\d+を書こうとするとエラーになります。

C#
// エラーになりやすい例
string pattern = "\d+";

正しくは、バックスラッシュを二重にします。

C#
string pattern = "\\d+";

または、逐語的文字列リテラルを使います。

C#
string pattern = @"\d+";

正規表現では、@"\d+"のように書くのが一般的です。

9-2. @を付けた逐語的文字列リテラルの使い方

@を付けた文字列は、バックスラッシュをそのまま扱える文字列です。

C#
string pattern = @"\d+";

正規表現ではバックスラッシュをよく使うため、@を付けるとコードが読みやすくなります。

ただし、ダブルクォーテーションを文字列内に含める場合は、""のように2つ重ねます。

C#
string pattern = @"id=""\d+""";

このように、逐語的文字列リテラルには独自の書き方がある点に注意しましょう。

9-3. 大文字小文字を区別したくない場合

通常、正規表現は大文字小文字を区別します。

C#
Match match = Regex.Match("Hello", @"hello");

Console.WriteLine(match.Success);

実行結果は次のようになります。

False

大文字小文字を区別したくない場合は、RegexOptions.IgnoreCaseを指定します。

C#
Match match = Regex.Match("Hello", @"hello", RegexOptions.IgnoreCase);

Console.WriteLine(match.Success);

実行結果は次のようになります。

True

9-4. 改行を含む文字列でうまく一致しない場合

.は任意の1文字に一致しますが、標準では改行には一致しません。

C#
string text = "start\nhello\nend";
Match match = Regex.Match(text, @"start.*end");

Console.WriteLine(match.Success);

この場合、期待どおりに一致しないことがあります。

改行も含めて.で一致させたい場合は、RegexOptions.Singlelineを使います。

C#
Match match = Regex.Match(text, @"start.*end", RegexOptions.Singleline);

Console.WriteLine(match.Success);

また、複数行の行頭や行末を扱いたい場合は、RegexOptions.Multilineを使います。

9-5. 正規表現が複雑すぎて読みづらくなる問題

正規表現は強力ですが、複雑になりすぎると読みづらくなります。

たとえば、ひとつのパターンに多くの条件を詰め込みすぎると、後から見たときに意味がわかりにくくなります。

C#
string pattern = @"^([a-zA-Z0-9_\.-]+)@([a-zA-Z0-9\.-]+)\.([a-zA-Z]{2,})$";

このような場合は、変数名をわかりやすくしたり、コメントを追加したり、名前付きグループを使ったりすると保守しやすくなります。

C#
string emailPattern = @"^[^@\s]+@[^@\s]+\.[^@\s]+$";

正規表現は短く書けることよりも、意図が伝わることを優先しましょう。

10. RegexOptionsでMatchの動作を変える

Regex.Matchには、検索方法を変えるためのRegexOptionsを指定できます。

10-1. IgnoreCaseで大文字小文字を無視する

RegexOptions.IgnoreCaseを使うと、大文字小文字を区別せずに検索できます。

C#
string text = "Hello C#";
Match match = Regex.Match(text, @"hello", RegexOptions.IgnoreCase);

if (match.Success)
{
Console.WriteLine(match.Value);
}

実行結果は次のようになります。

Hello

ユーザー入力や英単語検索では、大文字小文字を無視したい場面がよくあります。

10-2. Multilineで複数行の行頭・行末を扱う

RegexOptions.Multilineを使うと、^$が各行の先頭・末尾にも一致するようになります。

C#
string text = "apple\nbanana\ncherry";
Match match = Regex.Match(text, @"^banana$", RegexOptions.Multiline);

Console.WriteLine(match.Success);

実行結果は次のようになります。

True

ログや複数行テキストを扱う場合に便利です。

10-3. Singlelineでドットに改行も一致させる

RegexOptions.Singlelineを使うと、.が改行にも一致するようになります。

C#
string text = "start\nhello\nend";
Match match = Regex.Match(text, @"start.*end", RegexOptions.Singleline);

Console.WriteLine(match.Success);

実行結果は次のようになります。

True

HTMLや複数行のテキストから範囲を抽出したい場合などに使います。

ただし、.*は広い範囲に一致しやすいため、必要に応じて慎重に使いましょう。

10-4. Compiledを使う場合の考え方

RegexOptions.Compiledを指定すると、正規表現をコンパイルして実行できます。

C#
Regex regex = new Regex(@"\d+", RegexOptions.Compiled);
Match match = regex.Match("abc123");

同じ正規表現を何度も繰り返し使う場合、Compiledによって実行時の処理が効率的になることがあります。

ただし、初期化コストもあるため、1回だけの検索に必ず使うべきものではありません。

単発の処理では通常のRegex.Matchで十分です。大量に繰り返す処理やパフォーマンスが問題になる場面で検討しましょう。

10-5. タイムアウト指定で安全に実行する

複雑な正規表現やユーザー入力を扱う場合、正規表現の処理に時間がかかりすぎることがあります。

安全性を高めるには、タイムアウトを指定してRegexインスタンスを作成します。

C#
var regex = new Regex(@"\d+", RegexOptions.None, TimeSpan.FromSeconds(1));

Match match = regex.Match("abc123");

if (match.Success)
{
Console.WriteLine(match.Value);
}

特に、外部から入力された文字列に対して正規表現を実行する場合は、タイムアウトを設定しておくと安心です。

11. Regex.Match・Regex.Matches・Regex.IsMatchの違い

C#の正規表現では、Regex.MatchRegex.MatchesRegex.IsMatchをよく使います。

名前が似ていますが、目的が異なります。

11-1. Regex.Matchは最初の一致結果を取得する

Regex.Matchは、最初に一致した結果をMatchオブジェクトとして返します。

C#
Match match = Regex.Match("A1 B2 C3", @"\d");

Console.WriteLine(match.Value);

実行結果は次のようになります。

1

一致した文字列や位置、グループを取得したい場合に使います。

11-2. Regex.Matchesはすべての一致結果を取得する

Regex.Matchesは、一致したすべての結果をMatchCollectionとして返します。

C#
MatchCollection matches = Regex.Matches("A1 B2 C3", @"\d");

foreach (Match match in matches)
{
Console.WriteLine(match.Value);
}

実行結果は次のようになります。

1
2
3

複数の値を抽出したい場合に使います。

11-3. Regex.IsMatchは一致するかだけをboolで返す

Regex.IsMatchは、一致するかどうかだけをboolで返します。

C#
bool result = Regex.IsMatch("A1", @"\d");

Console.WriteLine(result);

実行結果は次のようになります。

True

一致した文字列そのものが不要な場合に向いています。

11-4. 目的別の使い分け早見表

目的使うメソッド戻り値
一致するかだけ判定したいRegex.IsMatchbool
最初の一致を取得したいRegex.MatchMatch
すべての一致を取得したいRegex.MatchesMatchCollection
一致した文字列の位置を知りたいRegex.MatchMatch
グループを使って一部を取り出したいRegex.MatchまたはRegex.MatchesMatch

11-5. 初心者が迷いやすい選び方

初心者のうちは、次のように考えると迷いにくくなります。

入力チェックだけならRegex.IsMatchです。

C#
bool isNumber = Regex.IsMatch(input, @"^\d+$");

最初に見つかった値を取り出すならRegex.Matchです。

C#
Match match = Regex.Match(input, @"\d+");

複数の値を取り出すならRegex.Matchesです。

C#
MatchCollection matches = Regex.Matches(input, @"\d+");

「判定」「1件抽出」「複数抽出」のどれが目的かを先に考えると、適切なメソッドを選びやすくなります。

12. C#のMatchを使った実践サンプル

ここでは、実際の開発で使いやすいRegex.Matchのサンプルを紹介します。

12-1. 文字列から数字だけを抽出する

C#
string text = "注文数は15個です";
Match match = Regex.Match(text, @"\d+");

if (match.Success)
{
int number = int.Parse(match.Value);
Console.WriteLine(number);
}

この例では、文字列から数字を取り出し、int.Parseで数値に変換しています。

金額、年齢、数量、IDなどの抽出に使えます。

12-2. ログ文字列から日時を取り出す

C#
string log = "[2026-06-19 10:30:45] Error occurred";
string pattern = @"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}";

Match match = Regex.Match(log, pattern);

if (match.Success)
{
Console.WriteLine("日時: " + match.Value);
}

実行結果は次のようになります。

日時: 2026-06-19 10:30:45

ログ解析では、日時、エラーコード、ユーザーIDなどを取り出す場面でRegex.Matchが役立ちます。

12-3. ファイル名から拡張子を判定する

C#
string fileName = "report.pdf";
Match match = Regex.Match(fileName, @"\.pdf$");

if (match.Success)
{
Console.WriteLine("PDFファイルです");
}

\.pdf$は、文字列の末尾が.pdfで終わることを表します。

大文字小文字を無視したい場合は、RegexOptions.IgnoreCaseを使います。

C#
Match match = Regex.Match(fileName, @"\.pdf$", RegexOptions.IgnoreCase);

12-4. 入力値がメールアドレス形式か確認する

C#
string input = "user@example.com";
string pattern = @"^[^@\s]+@[^@\s]+\.[^@\s]+$";

if (Regex.IsMatch(input, pattern))
{
Console.WriteLine("メールアドレス形式です");
}
else
{
Console.WriteLine("メールアドレス形式ではありません");
}

判定だけでよい場合は、Regex.MatchよりもRegex.IsMatchのほうがシンプルです。

ただし、メールアドレスからユーザー名やドメインを取り出したい場合は、Regex.MatchGroupsを使うと便利です。

C#
string email = "user@example.com";
string pattern = @"^(?<user>[^@\s]+)@(?<domain>[^@\s]+)$";

Match match = Regex.Match(email, pattern);

if (match.Success)
{
Console.WriteLine(match.Groups["user"].Value);
Console.WriteLine(match.Groups["domain"].Value);
}

12-5. HTML文字列から特定の属性値を取り出す

簡単なHTML文字列からhref属性を取り出す例です。

C#
string html = "<a href=\"https://example.com\">Example</a>";
string pattern = "href=\"([^\"]+)\"";

Match match = Regex.Match(html, pattern);

if (match.Success)
{
Console.WriteLine(match.Groups[1].Value);
}

実行結果は次のようになります。

https://example.com

ただし、HTML全体を本格的に解析する場合は、正規表現だけで処理するよりもHTMLパーサーを使うほうが安全です。

Regex.Matchは、形式が決まっている短い文字列から特定の属性値を取り出すような用途に向いています。

13. C#のMatchを使うときのベストプラクティス

最後に、Regex.Matchを使うときに意識したいポイントを整理します。

13-1. 判定だけならIsMatchを使う

一致したかどうかだけを知りたい場合は、Regex.IsMatchを使うとコードが簡潔になります。

C#
if (Regex.IsMatch(input, @"^\d+$"))
{
Console.WriteLine("数字のみです");
}

Matchオブジェクトが不要な場面では、IsMatchを使うのがおすすめです。

13-2. 複数抽出ならMatchesを使う

複数の一致を取り出したい場合は、Regex.Matchesを使います。

C#
MatchCollection matches = Regex.Matches("A1 B2 C3", @"\d");

foreach (Match match in matches)
{
Console.WriteLine(match.Value);
}

最初の1件だけならMatch、すべて取り出すならMatchesと使い分けましょう。

13-3. 複雑な正規表現はコメントや変数名で補足する

正規表現は短く書ける反面、意味がわかりにくくなりがちです。

C#
string postalCodePattern = @"^\d{3}-\d{4}$";

このように、変数名に意味を持たせるだけでも読みやすくなります。

さらに複雑な場合は、コメントを追加すると保守しやすくなります。

C#
// 郵便番号: 123-4567 の形式
string postalCodePattern = @"^\d{3}-\d{4}$";

13-4. ユーザー入力を扱う場合はタイムアウトを設定する

ユーザーが入力した文字列に対して複雑な正規表現を実行する場合、処理に時間がかかりすぎる可能性があります。

そのため、必要に応じてタイムアウトを指定しましょう。

C#
var regex = new Regex(pattern, RegexOptions.None, TimeSpan.FromSeconds(1));

Match match = regex.Match(input);

外部入力を扱うWebアプリやAPIでは、安全性を意識することが重要です。

13-5. 可読性を優先して名前付きグループを活用する

グループを使う場合は、番号だけでなく名前付きグループを活用すると読みやすくなります。

C#
string pattern = @"(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})";
Match match = Regex.Match("2026-06-19", pattern);

if (match.Success)
{
Console.WriteLine(match.Groups["year"].Value);
Console.WriteLine(match.Groups["month"].Value);
Console.WriteLine(match.Groups["day"].Value);
}

Groups[1]よりもGroups["year"]のほうが、何を取得しているのか明確です。

後からコードを読む人にも意図が伝わりやすくなります。

まとめ

C#のMatchは、正規表現に一致した結果を表すオブジェクトです。

Regex.Matchを使うと、文字列の中から正規表現パターンに一致する最初の部分を取得できます。

基本的な流れは次のとおりです。

C#
Match match = Regex.Match(input, pattern);

if (match.Success)
{
Console.WriteLine(match.Value);
}

match.Successで一致したかを判定し、match.Valueで一致した文字列を取得します。

さらに、Indexで開始位置、Lengthで文字数、Groupsで部分的な値を取得できます。

判定だけならRegex.IsMatch、最初の一致を取得するならRegex.Match、複数の一致を取得するならRegex.Matchesを使うとよいでしょう。

Regex.Matchは、数値の抽出、日付の取得、メールアドレスや電話番号の判定、ログ解析、URL抽出など、さまざまな場面で役立ちます。

初心者のうちは、まずSuccessValueGroupsの使い方を押さえることが大切です。慣れてきたら、RegexOptionsや名前付きグループ、タイムアウト指定も活用して、安全で読みやすいコードを書いていきましょう。