.NET & Control > .NET Regex「正規表現」テクニック
のぶ亭『プログラミングの相談窓口』 … 様々なプログラミング問題を個別対応致します |
.NET Regex「正規表現」テクニック
パターンを見つけて必要な情報を抽出・置き換え(削除)を行う方法
Google、Yahoo、動画サイト等の検索ページ、一覧ページ等を分析・追跡して、検索結果、画像の取得、動画の取得するにはどうすればいいでしょうか?ページを取得して、必要な情報を取り出せばいいのです。
「正規表現」とは、このように情報からパターンを見つけて、欲しい情報だけを取り出す、見つけた情報を置き換えるなど高度な処理を行うため技術です。
Windowsプログラマーの方にとっては、正規表現は馴染みがないかもしれません。例えば、HTMLやXMLなどは、DOMという技術を使ってタグをTree階層にして調べていく・・・といった方法をよく使います。
ところが、ドキュメント全体をTree階層にするため、(サイズにもよりますが)結構時間がかかってしまいます。複数のHTMLやXMLをその都度DOMで対応してもいいですが、体系化せずに直接抽出したいパターンを見つけて取り出す方が高速に処理することができます。
*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
Windows系で検索といえば*?等を使った「ワイルドカード」です。
正規表現は、もっと複雑で高度な検索(抽出)ができる「パターン」を指定することができます。ただし、この「パターン」は方言・・・規格統一されていないため、それぞれの実行環境で同じ結果になるとは限りません。grep、Java、Javascript、Pearl、PHP、.NET Framework、様々なエディタ・・・といった感じで、結果の違いだけでなく、機能そのものがサポートされていたり、いなかったりしますので注意してください。
ここでは、.NET FrameworkのClass Library「正規表現」を使って学習していきます。
どうすれば何ができるのか?
実際にやってみてその「価値が理解」できなければ、真剣に学習することはできません。やる気になりません。
パターンは複雑です。マニュアルを読んで意味を理解しただけではとても使いこなせません。
「正規表現シミュレータ」ソフトを使って、実際に正規表現を試してその価値(メリット)を肌で感じてください。 RegEx Tester - Regular Expression Tester - CodeProject ソースコード付
正規表現
- 正規表現の基本
- 正規表現で何ができるか
- パターンはどのように書けばよいか?
- 簡単な例
- メタ文字一覧
- ある1文字を表す文字(アトム)
- 文字列内の位置を表す文字(アトミックゼロ幅アサーション、アンカー、位置指定子)
- 文字の繰り返しを表す文字(量指定子)
- 選択、グループ化などを表す文字
- 前方参照(後方参照)を表す文字
- 置換パターンで使用できる特殊文字
- よく使われるオプション
- 最長マッチと最短マッチ
正規表現の基本
ここでは.NET Frameworkの正規表現について基本をごく簡単に(主に正規表現パターンについて)説明します。なお.NET Frameworkの正規表現はPerl5の正規表現に対応するようにデザインされているということなので、Perlの正規表現を理解していれば問題ありません。
正規表現で何ができるか
正規表現は、文字列を検索するために使用します。正規表現を使うと、かなり複雑な検索が可能です。正規表現を利用する主なケースには以下のようなものが挙げられます。
- 文字列内に指定されたパターンと一致する部分があるか調べる。例えば、入力された文字列が電子メールアドレスとして適当か調べるなど。
- 文字列から指定されたパターンと一致する部分を検索、抽出する。例えば、文字列内にあるURLの部分をすべて抜き出すなど。
- 文字列から指定されたパターンと一致する部分を探して別の文字列に置換する。例えば、文字列内にあるURLにリンク(<a>タグ)を付けたり、HTMLのタグを削除するなど。
補足:これら以外にも、文字列を分割して配列にする場合にも使用できます。この場合は、Regex.Splitメソッドを使います。
パターンはどのように書けばよいか?
「こんな文字列が出てくる部分を探して」ということを指定するには、それを表現したパターンを書く必要があります。適切なパターンを書けるようになることが、正規表現を勉強する最大の目標となるでしょう。
パターンは、ファイルの検索などで使用される「*」や「?」などのワイルドカードをご存じの方ならば、これと同じようなものだと思っていただいて結構です。
例えば、文字列からある郵便番号と一致する部分を探したいとします。その郵便番号が決まっており、「123-4567」であるならば、パターンは「123-4567」のままでOKです。ただし、このように探したい文字列が決まっているならば、正規表現を使う意味がありません。
決まった郵便番号ではなく、郵便番号っぽい文字列を探したい、つまり、「何らかの数字が3つ続き、-(ダッシュ)が挟まり、また数字が4つ続く文字列」を探したいということであれば、正規表現が役に立ちます。このような場合、書くべきパターンは、「\d\d\d-\d\d\d\d」となります(別の書き方もできます)。つまり、「\d」は「何らかの数字1文字」を意味します。
このように正規表現のパターンでは、「\」などの特定の文字列が特別な意味を持っています。このような特別な意味を持つ文字を「メタ文字」(メタキャラクタ)と呼びます。
簡単な例
.NETで正規表現を扱うには、Regexクラスを使います。以下にRegexクラスを使って文字列の検査、抽出、置換を行う簡単な例を示します。より詳しい例については、「正規表現を使って文字列がある形式と一致するか調べる」、「正規表現を使って文字列を検索し、抽出する」、「正規表現を使って文字列を置換する」をご覧ください。
//TextBox1に郵便番号っぽい文字列が含まれているか調べる if (System.Text.RegularExpressions.Regex.IsMatch( TextBox1.Text, @"\d\d\d-\d\d\d\d")) { Console.WriteLine("郵便番号が含まれています"); } //TextBox1内の郵便番号っぽい文字列をすべて抽出する System.Text.RegularExpressions.MatchCollection mc = System.Text.RegularExpressions.Regex.Matches( TextBox1.Text, @"\d\d\d-\d\d\d\d"); foreach (System.Text.RegularExpressions.Match m in mc) { Console.WriteLine(m.Value); } //TextBox1内の郵便番号っぽい文字列の"-"を削除して、【】で囲む TextBox1.Text = System.Text.RegularExpressions.Regex.Replace( TextBox1.Text, @"(\d\d\d)-(\d\d\d\d)", "【$1$2】");
メタ文字一覧
以下によく使われるメタ文字とその意味を紹介します。詳しくはMSDNの「正規表現言語要素」をご覧ください。
ある1文字を表す文字(アトム)
文字
説明
使用例
.(ピリオド)
改行文字(\n)以外の任意の一文字。(ただし [] 内ではピリオド文字。)
「.」
「」内に任意の1文字がある箇所にマッチ
\s
空白文字。改行文字、タブ文字、半角/全角スペース文字など。[\f\n\r\t\v\x85\p{Z}]と同じ。
(ちなみに \S は \s 以外の文字を表す。)Visual\sBasic
Visual と Basic
の間に空白文字が1文字ある箇所にマッチ
\d
0から9までの数字。全角を含む。\p{Nd}と同じ。
(ちなみに \D は \d
以外の文字を表す。)VB\d
VB の後に数字が1文字ある箇所にマッチ
\w
単語に使用される文字。アルファベット、数字、アンダーバー(_)、ひらがな、カタカナ、漢字など。[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}\p{Lm}]と同じ。
(ちなみに \W は \w 以外の文字を表す。)「\w」
「」内に単語に使用される文字が1文字がある箇所にマッチ
\r
キャリッジリターン。\u000Dと同じ。
\r\n
Windows の改行文字(CRLF)にマッチ
\n
ラインフィールド(改行文字)。\u000Aと同じ。
\r\n
Windows の改行文字(CRLF)にマッチ
\t
タブ。\u0009と同じ。
\n\t
改行文字(\n)の後にタブが続く箇所にマッチ
\\
文字の前に \
を付けると、その文字。メタ文字の機能を無効にするときに使う。(ある文字列内のメタ文字をすべて \
でエスケープするには、Regex.Escapeメソッドを使うとよい。)
DOBON\.NET
DOBON.NET にマッチ
[ ]
[]内のどれか1文字。[abc]ならば、aかbかc。
VB[2456]
VB の後に2か4か5か6が続く箇所にマッチ
[^ ]
[^]内の文字以外の1文字。[^abc]ならば、aかbかc以外の文字。
「[^「」]」
「」内に「」以外の1文字がある箇所にマッチ
[ - ]
連続した文字範囲の1文字。[0-9]ならば、数字1文字。[a-zA-Z]ならば、アルファベット1文字。
VB[24-6]
VB の後に 2か4か5か6 が続く箇所にマッチ
\u0000
4桁の16進数で表されるUnicode文字。
[\uFF61-\uFF9F]
半角カナ文字の1文字にマッチ(詳細)
\x00
2桁の16進数で表されるASCII文字。
[\x20-\x7F]
半角英数記号文字(0x20~0x7F)の1文字にマッチ
終わりに
正規表現を使った置換処理を紹介しました。特にキャプチャを使った置換処理が強力だということが分かっていただけたでしょうか。正規表現はプログラムの中だけではなくテキストエディタ等でも利用できますので、利用できる場面は多いと思います。
ここで紹介したものがすべてではありません。より詳しく知りたい方はネットで調べたり本を読んだりして下さい。本気で勉強するのであれば「詳説
正規表現」がお勧めです。