Home > C# > C# 学び直し > 正規表現

ベクトルドロー・レベルゼロ

C#で正規表現を使用する

広告

新規作成日 2017-11-14/
最終更新日

C#は、文字列を簡単に扱うことができる開発言語の1つです。文字列から、特定の文字列を検索したり、置換する際に、正規表現を使用すると、複雑な文字列操作を行うことができます。

特に、大きな文字列から、必要な文字列だけを取り出す場合は、正規表現を使うと便利です。正規表現は、多くのアプリケーションや開発言語で利用する事ができます。

C#では、正規表現を扱うためのクラスが用意されているので、正規表現エンジンと呼ばれる正規表現を処理するプログラムを自分でプログラミングすることなく、プログラム中で正規表現の表現を使って処理したり、アプリケーションに正規表現を使用した機能を提供することが可能です。

正規表現は、アプリケーションや開発言語によって微妙に異なり、いわゆる方言を持っています。C#では、.Net Freameworkの正規表現を使うことになります。

C#で、正規表現を使うためには、次の2つのことを同時に扱うことになります。

  • 正規表現の使い方
  • C#で、正規表現を使ったプログラムを作成する方法

正規表現に慣れ親しんでいない場合、2つのことを、新たに同時に扱うことになります。混乱しないように理解するためには、どちらの内容か判断して、混同しないことが大切です。

正規表現パターンをうまく組み立てると文字列から目的とする部分だけを検索したり、置換することができます。ただ、使いこなすためには、それなりの経験が必要です。

はじめから、全てを理解しようとするのでは無く、まずは、C#で、正規表現を使用する方法を学ぶことを優先し、正規表現パターンについては、いろいろな場所で紹介されているパターンの代表的なものを活用するところから始めましょう。 それだけでも、かなり便利になります。その後、必要に応じて、自在に正規表現パターンを扱える技能の取得を目指して下さい。

正規表現パターンを集める

正規表現は、アプリケーションや開発言語によって微妙に異なり、いわゆる方言を持っています。しかし、正規表現パターンを利用する参考になるので、サンプル集やチートシートのリンクは、集めておくと役に立つことが多いです。

指定したパターンに一致する部分文字列を持っているか判定する

指定したパターンに一致する部分文字列を持っているか確認する操作は、主に、入力した文字列が期待したパターンに準拠しているかを判別し、適合していない場合、再入力を求める入力文字列の妥当性検証を行う際に利用されます。

指定したパターンに一致する部分文字列を持っているか確認する場合、RegexクラスのIsMatchメソッドを使用します。

Regex.IsMatchメソッドは、入力文字列が、指定したパターンに一致する部分文字列を持っているか判定するメソッドです。

is、can、hasが頭につくメソッドは、bool型の値を返します。

isの場合は、「A is B」(AはBである)をの意味で、その答えをtrue(真)あるいはfalse(偽)で返すと考えればわかりやすいかと思います。

具体的な利用方法としては、数字の桁数やハイフンの位置を判断して、郵便番号や電話番号、@の有無を判断してメールアドレスなどの特定の形式のデータにあからさまに間違った値が入力されていないか、確認する際に使用されます。ユーザーに入力を求める操作で、ユーザーが入力した値が適切な値かどうか判断する妥当性検証に用いることが主な用途です。 不適切であれば、すぐにユーザーに入力した値の再入力を求める事ができます。

翻訳した、msdnのRegex.IsMatchメソッドの説明

次の例は、正規表現パターンを検証する際に利用できるプログラムです。使用する正規表現が意図した文字列を認識するかを確認するプログラムを作成する事ができます。

Regex.IsMatch メソッド (String, String)

using System;
using System.Text.RegularExpressions;

namespace RegularExperssion02
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] partNumbers = {
                "1234-5678",
                "12345678",
                "1235-45",
                "123-1567"};

            string pattern = @"^\d{4}-*\d{4}$";

            foreach (string partNumber in partNumbers)
                Console.WriteLine("{0}は、郵便番号で{1} 。",
                                  partNumber,
                                  Regex.IsMatch(partNumber, pattern) ? "す" : "はありません");

            // Keep the console window open in debug mode.
            // デバッグモードで、コンソール・ウインドウを開いた状態に維持します。
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }
    }
}

Regex.IsMatch メソッド (String)

using System;
using System.Text.RegularExpressions;

namespace RegularExperssion02
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] partNumbers = {
                "1234-5678",
                "12345678",
                "1235-45",
                "123-1567"};

            Regex rgx = new Regex(@"^\d{4}-*\d{4}$");

            foreach (string partNumber in partNumbers)
                Console.WriteLine("{0}は、郵便番号で{1} 。",
                                  partNumber,
                                  rgx.IsMatch(partNumber) ? "す" : "はありません");

            // Keep the console window open in debug mode.
            // デバッグモードで、コンソール・ウインドウを開いた状態に維持します。
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }
    }
}

指定したパターンに一致する部分文字列を見つける、取り出す

指定したパターンに一致する部分文字列を見つける、あるいは、取り出すには、Regex クラスのMatchメソッドとMatchクラスのNextMatch ()メソッドの組み合わせ、あるいは、Regex クラスのMatchesメソッドを使用します。

また、一致した部分文字列は、Match クラスに格納します。

msdnのMatchクラスの説明を翻訳した

MatchメソッドとNextMatch ()メソッドの組み合わせは、1つずつ結果を取得する際に使用し、Matchesメソッドは、一度に結果を取得する際に、使用します。対象とする文字列が大きければ、あるいは、結果を1つ1つ処理する際は、MatchメソッドとNextMatch ()メソッドの組み合わせを使用し、1つずつ結果を処理し、文字列が小さければ、あるいは、その後の処理に一致した結果全てを使用する場合は、Matchesメソッドを使って、まとめて結果を取得したのち、その結果を後で処理すると理解しておけば良いかと思います。ほとんどの場合、どちらを使用しても違いはありません。

MatchメソッドとNextMatch ()メソッドの組み合わせを使用する

Regex クラスのMatchesメソッドは、指定したパターンに一致する最初の部分文字列しか見つける事ができません。それ以降の指定したパターンに一致する部分文字列は、MatchクラスのNextMatch ()メソッドを使用します。

結果は、実行するたびに1つだけ取得されます。そのため、一致した結果を1つ1つ処理する場合、プログラムは、直感的な動作になり、一致結果を保存しておく必要もありません。

プログラムは、特徴的な構造をしているので、考えるのではなく雛形を覚えて使いまわす形で使用すると良いかと思います。

結果は、Matchクラスに格納します。

関連する資料では、Matchオブジェクトという表現も登場します。MatchクラスとMatchオブジェクトの用語の使い分けはよくわかりませんが、Matchクラス内のデータをMatchオブジェクトと表現すると理解しておけば、大きく間違っていることはないと思います。

返されたMatchオブジェクトのSuccessプロパティの値を確認することで、正規表現パターンが入力文字列で見つかったかどうかを判断することができます。

一致が見つかると、返されたMatchオブジェクトのValueプロパティには、正規表現パターンに一致する入力から、部分文字列が含まれています。一致するものが見つからない場合、その値はString.Emptyです。

返されたMatchオブジェクトのMatch.NextMatchメソッドを繰り返し呼び出すことによって、次の一致を検索することができます。

正規表現を使って検索を行うと、検索する文字列そのものではなく、正規表現パターンで指定した特定のパターンを持つ文字列全てを検索することができます。

msdnのRegex.Matchメソッドの説明を翻訳した

msdnのMatch.NextMatch()メソッドの説明を翻訳した。

Regex.Match メソッド (String)

Regex.Match メソッド (String)は、インスタンスを作成する必要があります。同じ正規表現パターンをループの中で繰り返し使う場合は、あらかじめインスタンスを作成する必要のあるこちらのメソッドを使用すると処理速度の向上が期待できます。

using System;
using System.Text.RegularExpressions;

namespace RegularExperssion03
{
    class Program
    {
        static void Main(string[] args)
        {
            string text = "正規表現を使って検索を行うと、検索する文字列そのものではなく、正規表現パターンで指定した特定のパターンを持つ文字列全てを検索することができます。";
            string pat = @"検索";

            // Instantiate the regular expression object.
            // 新しい正規表現オブジェクトをインスタンス化します。
            Regex r = new Regex(pat, RegexOptions.IgnoreCase);

            // Match the regular expression pattern against a text string.
            // テキスト文字列に正規表現パターンが一致します。
            Match m = r.Match(text);
            while (m.Success)
            {
                Console.WriteLine("「{0}」が見つかった場所は {1}", m.Value, m.Index);
                m = m.NextMatch();
            }
            // Keep the console window open in debug mode.
            // デバッグモードで、コンソール・ウインドウを開いた状態に維持します。
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }
    }
}

Regex.Match メソッド (String, String)

Regex.Match メソッド (String, String)は、インスタンスを作成する必要がありません。

using System;
using System.Text.RegularExpressions;

namespace RegularExperssion03
{
    class Program
    {
        static void Main(string[] args)
        {
            string text = "正規表現を使って検索を行うと、検索する文字列そのものではなく、正規表現パターンで指定した特定のパターンを持つ文字列全てを検索することができます。";
            string pattern = @"検索";

            // Match the regular expression pattern against a text string.
            // テキスト文字列に正規表現パターンが一致します。
            Match m = Regex.Match(text, pattern);
            while (m.Success)
            {
                Console.WriteLine("「{0}」が見つかった場所は {1}", m.Value, m.Index);
                m = m.NextMatch();
            }
            // Keep the console window open in debug mode.
            // デバッグモードで、コンソール・ウインドウを開いた状態に維持します。
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }
    }
}

Matchesメソッドの組み合わせを使用する

Matchesメソッドを使用すると、Matchクラスで、正規表現パターンの最初の一致を取得し後、NextMatch ()メソッドを繰り返すことなく、全ての一致を取得することができます。

取得した一致を1つ1つ処理するのではなく、まとめて処理する場合に便利です。

msdnのRegex.Matchesメソッドの説明を翻訳した

msdnのMatchCollectionクラスの説明を翻訳した

Regex.Matches メソッド (String)

using System;
using System.Text.RegularExpressions;

namespace RegularExperssion04
{
    class Program
    {
        static void Main(string[] args)
        {
            string text = "正規表現を使って検索を行うと、検索する文字列そのものではなく、正規表現パターンで指定した特定のパターンを持つ文字列全てを検索することができます。";
            string pattern = @"検索";

            // Instantiate the regular expression object.
            // 新しい正規表現オブジェクトをインスタンス化します。
            Regex rgx = new Regex(pattern);

            foreach (Match match in rgx.Matches(text))
            {
                Console.WriteLine("「{0}」が見つかった場所は {1}", match.Value, match.Index);
            }
            // Keep the console window open in debug mode.
            // デバッグモードで、コンソール・ウインドウを開いた状態に維持します。
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }
    }
}

Regex.Matches メソッド (String, String)

using System;
using System.Text.RegularExpressions;

namespace RegularExperssion04
{
    class Program
    {
        static void Main(string[] args)
        {
            string text = "正規表現を使って検索を行うと、検索する文字列そのものではなく、正規表現パターンで指定した特定のパターンを持つ文字列全てを検索することができます。";
            string pattern = @"検索";

            foreach (Match match in Regex.Matches(text, pattern))
            {
                Console.WriteLine("「{0}」が見つかった場所は {1}", match.Value, match.Index);
            }
            // Keep the console window open in debug mode.
            // デバッグモードで、コンソール・ウインドウを開いた状態に維持します。
            System.Console.WriteLine("Press any key to exit.");
            System.Console.ReadKey();
        }
    }
}
このエントリーをはてなブックマークに追加

広告

Home PC C# Illustration

Copyright (C) 2011-2016 Horio Kazuhiko(kukekko) All Rights Reserved.
kukekko@gmail.com
ご連絡の際は、お問い合わせページのURLの明記をお願いします。
「掲載内容は私自身の見解であり、所属する組織を代表するものではありません。」