正規表現マスターへの道!C#で学ぶ、パターンマッチングの極意
プログラミングにおいて、テキストデータを扱う場面は非常に多いですよね。そんな時、効率的に文字列の検索、置換、抽出を行うための強力なツールが、正規表現です。
この記事では、C#言語を使用して、正規表現のさまざまなパターンについて学んでいきます。具体的なソースコード例と出力結果を交えながら、各正規表現のパターンがどのように機能するのかを解説します。
さあ、一緒に正規表現のマスターを目指しましょう!
KindleUnlimited会員であれば、全ての本をご覧頂けます。 Linqを理解すれば、C#プログラミングの世界が変わる 第1版
正規表現の一覧
No | Symbol | Description |
1 | ^ | 文字列または行の開始を意味します。 |
2 | $ | 文字列または行の終了を意味します。 |
3 | . (ドット) | 任意の単一文字を意味します(改行文字を除く)。 |
4 | [ ] | 文字の集合を定義し、その集合内の任意の一文字にマッチします。 |
5 | [^ ] | 括弧内の文字を除く任意の一文字にマッチします。 |
6 | | | 代替、つまり論理的な「OR」を意味します。 |
7 | ( ) | グループを作成し、キャプチャ(情報の抽出)します。 |
8 | * | 直前の文字が0回以上繰り返されることを意味します。 |
9 | + | 直前の文字が1回以上繰り返されることを意味します。 |
10 | ? | 直前の文字が0回または1回出現することを意味します。 |
11 | {n} | 直前の項目が正確にn回出現することを意味します。 |
12 | {n,} | 直前の項目がn回以上出現することを意味します。 |
13 | {n,m} | 直前の項目がn回以上、m回以下出現することを意味します。 |
14 | \d | 任意の数字にマッチします([0-9]と同じ)。 |
15 | \D | 数字以外の任意の文字にマッチします。 |
16 | \w | 「単語文字」にマッチします(英数字またはアンダースコア)。 |
17 | \W | 「単語文字」以外の任意の文字にマッチします。 |
18 | \s | 任意の空白文字(スペース、タブ、改行、フォームフィード、キャリッジリターン)にマッチします。 |
19 | \S | 空白文字以外の任意の文字にマッチします。 |
20 | \b | 単語の境界を表します。 |
21 | \B | 単語の境界ではない位置を表します。 |
22 | \c | 制御文字にマッチします。 |
23 | \x | 16進表記による文字コードにマッチします。 |
24 | \u | Unicode文字にマッチします。 |
1. 「^」と「$」: 文字列の開始と終了
「^」は、文字列または行の開始を意味します。一方、「$」は文字列または行の終了を表します。これらは、特定の位置から開始または終了する文字列をマッチさせたい場合に使用されます。
ポイント
「^」と「$」は、それぞれ文字列の開始と終了にマッチするメタ文字です。文字列が特定のパターンで始まっているか、または終わっているかを確認する際に役立ちます。
step
1
「hello」で始まり、「world」で終わる文字列を検索する例を見てみましょう。
ソースコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using System; using System.Text.RegularExpressions; class Program { static void Main() { string pattern = @"^hello.*world$"; string input = "hello, how are you, world"; Match m = Regex.Match(input, pattern); if (m.Success) { Console.WriteLine("Match Found: " + m.Value); } else { Console.WriteLine("No match"); } } } |
出力結果
Match Found: hello, how are you, world
2. 「.」(ドット): 任意の単一文字
正規表現の「.」は、改行を除く任意の単一文字にマッチします。つまり、どんな文字でもいいから何かしらの文字があればいい、という場合に使用します。
ポイント
「.」は非常に汎用的なメタ文字です。しかし、「.」は改行文字にはマッチしないので、複数行にまたがるテキストを検索する際は注意が必要です。
step
2
「a」の後に任意の文字が1つあって、「c」が来る文字列を検索する例を見てみましょう。
ソースコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using System; using System.Text.RegularExpressions; class Program { static void Main() { string pattern = "a.c"; string input = "abc a&c a c adc"; foreach (Match m in Regex.Matches(input, pattern)) { Console.WriteLine("Match Found: " + m.Value); } } } |
出力結果
Match Found: abc
Match Found: a&c
そうですね、「.」は「何かしらの文字」なので、文字がないとマッチしないんです。だから、「a」と「c」の間に文字がない「a c」はマッチしません。
この記事は長くなってしまったので、ここで一旦終わりにしますが、次回は「*」、「+」、そして「?」について学んでいきます。これらのメタ文字を使うと、文字列の繰り返しパターンをもっと柔軟に制御できるようになります。
正規表現は最初は難しそうに感じるかもしれませんが、一度手に入れると非常に強力なツールです。ぜひ、続きもお楽しみに!
3. 「*」、「+」、そして「?」: 繰り返しパターン
正規表現では、特定の文字が何度も繰り返されるパターンを簡単に探すことができます。このためのメタ文字には、「*」、「+」、そして「?」があります。
ポイント
「*」は、直前の文字が0回以上の繰り返し、「+」は1回以上の繰り返し、「?」は0回または1回の出現を表します。これらを使うことで、さまざまな繰り返しパターンに対応できます。
step
3
それぞれのメタ文字がどのように機能するのか見ていきましょう。
「*」の使用例
ソースコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using System; using System.Text.RegularExpressions; class Program { static void Main() { string pattern = "lo*"; string input = "He lost his balloon in the flood."; foreach (Match m in Regex.Matches(input, pattern)) { Console.WriteLine("Match Found: " + m.Value); } } } |
出力結果
Match Found: l
Match Found: lo
Match Found: l
Match Found: loo
「+」の使用例
ソースコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using System; using System.Text.RegularExpressions; class Program { static void Main() { string pattern = "lo+"; string input = "He lost his balloon in the flood."; foreach (Match m in Regex.Matches(input, pattern)) { Console.WriteLine("Match Found: " + m.Value); } } } |
出力結果
Match Found: lo
Match Found: loo
「?」の使用例
ソースコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using System; using System.Text.RegularExpressions; class Program { static void Main() { string pattern = "lo?"; string input = "He lost his balloon in the flood."; foreach (Match m in Regex.Matches(input, pattern)) { Console.WriteLine("Match Found: " + m.Value); } } } |
出力結果
Match Found: lo
Match Found: l
Match Found: lo
はい、それらのメタ文字を組み合わせることで、より複雑なパターンにマッチさせることが可能です。繰り返しの概念は、テキスト検索やデータ抽出において非常に重要な要素ですので、これらのメタ文字の使い方をしっかり理解しておくことが重要です。
さらに進んで、次回は文字クラス、否定、量指定子など、さらに高度なパターンについて学んでいきましょう。正規表現の知識を深めることで、より複雑なテキスト処理もスムーズにこなせるようになります。
4. 文字クラス: 特定の文字グループにマッチ
文字クラスを使用すると、特定の文字セットのいずれかにマッチする正規表現を作成できます。これは、特定の種類の文字を捜索したり、入力データに予想される文字種を制限したりする場合に便利です。
ポイント
文字クラスは、角括弧([])を使用して定義されます。この中に設定したい文字のセットを記入します。例えば、[abc]は「a」、「b」、または「c」のいずれかにマッチします。
step
4
文字クラスを使用した検索の例をいくつか見てみましょう。
基本的な文字クラスの使用例
ソースコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using System; using System.Text.RegularExpressions; class Program { static void Main() { string pattern = "[abc]"; string input = "Would you like an apple, a banana, or a cherry?"; foreach (Match m in Regex.Matches(input, pattern)) { Console.WriteLine("Match Found: " + m.Value); } } } |
出力結果
Match Found: a
Match Found: a
Match Found: a
Match Found: b
Match Found: a
Match Found: c
否定文字クラスの使用例
また、否定文字クラスを使うこともできます。これは、特定の文字セットを除外してマッチさせるときに使用されます。例えば、「[^abc]」は「a」、「b」、「c」以外の任意の文字にマッチします。
ソースコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using System; using System.Text.RegularExpressions; class Program { static void Main() { string pattern = "[^abc]"; string input = "Would you like an apple, a banana, or a cherry?"; foreach (Match m in Regex.Matches(input, pattern)) { Console.WriteLine("Match Found: " + m.Value); } } } |
出力結果
Match Found: W
Match Found: o
Match Found: u
Match Found: l
Match Found: d
... (他のマッチした文字)
5. 量指定子: マッチの長さをコントロール
量指定子を使用すると、正規表現の一部が対象テキストで何回繰り返されるかを指定できます。これには、「{n}」、「{n,}」、そして「{n,m}」の形式があります。ここで「n」や「m」は整数です。
ポイント
「{n}」は正確にn回の出現、「{n,}」はn回以上の出現、「{n,m}」はn回からm回の出現を意味します。これにより、正確な繰り返し回数または繰り返し範囲を指定できます。
次回、これらの高度なコンセプトを使って、より複雑な検索パターンを作成する方法を学んでいきます。データバリデーション、検索、置換など、正規表現の強力な機能を最大限に活用しましょう!
量指定子の基本的な使用例
ここでは、"a"が連続して2回以上続く場所を見つけるシンプルな例を見てみましょう。
ソースコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
using System; using System.Text.RegularExpressions; class Program { static void Main() { string pattern = "a{2,}"; string input = "Candy, apple, and banana are on the table."; foreach (Match m in Regex.Matches(input, pattern)) { Console.WriteLine("Match Found: " + m.Value); } } } |
出力結果
Match Found: aa
この例では、"a{2,}"というパターンを使用して、2回以上連続する「a」を検索しています。結果として、"apple"の中の"aa"がマッチします。
複雑なパターンの構築
文字クラスと量指定子を組み合わせることで、特定の形式のテキスト構造、例えば、電話番号やメールアドレスなどを識別することが可能です。
step
5
電話番号を識別するための正規表現の例を以下に示します。
ソースコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
using System; using System.Text.RegularExpressions; class Program { static void Main() { // 電話番号の形式:3桁の数字、ハイフン、4桁の数字 string pattern = @"\b\d{3}-\d{4}\b"; string input = "会議は10時からです。連絡先は123-4567です。"; foreach (Match m in Regex.Matches(input, pattern)) { Console.WriteLine("電話番号が見つかりました: " + m.Value); } } } |
出力結果
電話番号が見つかりました: 123-4567
この例では、"\b\d{3}-\d{4}\b"という正規表現を使用しています。"\d{3}"は正確に3桁の数字、"-"はハイフン、"\d{4}"は正確に4桁の数字を意味します。また、"\b"は単語の境界を表します。このパターンは、日本の標準的な固定電話番号の形式に一致します。
これで、基本的な正規表現の書き方から、より複雑なパターンの作成方法まで、幅広いトピックをカバーしました。正規表現は非常に強力なツールであり、様々なテキスト処理タスクでその効果を発揮します。この知識を活用して、あなたのコーディング作業をより効率的に行いましょう!
グループ化と後方参照
グループ化は、複数の文字や表現を一つの単位として扱うためのものです。これにより、一致したテキストのサブセクションに簡単にアクセスしたり、条件付きで部分的にパターンを繰り返すことができます。
step
6
以下の例では、同じ単語が繰り返される場合にマッチする正規表現を作成します。
ソースコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
using System; using System.Text.RegularExpressions; class Program { static void Main() { // 同じ単語が繰り返される場合にマッチするパターン string pattern = @"\b(\w+)\s+\1\b"; string input = "Hello hello, how are you?"; foreach (Match m in Regex.Matches(input, pattern, RegexOptions.IgnoreCase)) { Console.WriteLine("繰り返しの単語が見つかりました: " + m.Value); } } } |
出力結果
繰り返しの単語が見つかりました: Hello hello
この例では、"\b(\w+)\s+\1\b"というパターンを使用しています。ここで"(\w+)"は単語文字を1回以上繰り返すグループ、"\s+"はスペース1つ以上、"\1"は先ほどのグループの内容を後方参照しています。大文字小文字を区別しないためのオプションも使用しています。
まとめ
今回のガイドでは、正規表現の基本的な概念から、文字クラス、量指定子、グループ化、後方参照といった高度なトピックに至るまでを解説しました。これらの知識を組み合わせることで、あらゆる種類のテキストパターンを識別し、構造化することができます。
正規表現は、テキストデータの処理において極めて強力なツールですが、その複雑さゆえに初学者にとっては難解に感じられるかもしれません。しかし、基本を理解し、実践を通じて徐々に経験を積んでいけば、あなたのコーディングスキルが飛躍的に向上することでしょう。
最後に、正規表現の学習は決して終わりではありません。常に新しいパターンが発見され、新しい問題が解決されています。この興味深い分野でのあなたの旅が、これからも続くことを願っています。