ASP.NET の正規表現

短期集中コース

Steven A. Smith

March 2004
日本語版最終更新日 2004 年 8 月 6 日

適用対象:
Microsoft® .NET Framework
Microsoft ASP.NET
正規表現 API

要約: 正規表現は、テキストを処理するための非常に便利なツールです。 ユーザー入力の検証、文字列内のパータン検索、または強力な方法でのテキストの再フォーマットのいずれを行う場合も、正規表現は役に立ちます。この記事には英語のページへのリンクも含まれています。

この記事のソース コードをダウンロードする

目次

はじめに
正規表現の簡単な歴史
単純な式
量指定子
メタ文字
文字クラス
あらかじめ定義されたメタ文字セット
サンプル式
ASP.NET での検証
正規表現 API
無料ツール
高度なトピック
まとめ
参考資料
著者紹介

はじめに

Microsoft.NET Framework における正規表現のサポートは非常に優れており、Microsoft ASP.NET にも正規表現の言語に基づくコントロールが備えられています。この記事では、正規表現の基礎について説明し、詳細情報の入手先を紹介します。

この記事は、ASP.NET および .NET でのプログラミングには精通しているが、正規表現についてあまりよく知らないか、まったく知らないという初心者を対象にしています。また、以前、正規表現を使用したことがある開発者は、ハンディ リファレンスとして、正規表現チャート シートも併せてご利用ください。この記事では、以下の事項について説明します。

  1. 正規表現の簡単な歴史
  2. 単純な式
  3. 量指定子
  4. メタ文字
  5. 文字クラス
  6. あらかじめ定義されたメタ文字セット
  7. サンプル式の詳細
  8. ASP.NET での検証
  9. 正規表現 API
  10. 無料ツール
  11. 高度なトピックの概要
  12. 要約と参考資料

この記事に関して、または正規表現全般について質問がある場合は、http://www.aspadvice.com/ Non-MS linkregex メーリング リスト (英語) Non-MS link までご質問をお寄せください。この Web サイトは、筆者が運営するもので、350 人以上の購読者がいます。

正規表現の簡単な歴史

今日存在する正規表現は、1950 年代に開発されたものです。正規表現は、本来、神経生理学者によって研究されているパターンであった "正則集合" を説明するために使用されました。正規表現における最初の功績者は、数学者 Stephen Kleene であると広く認知されています。最終的には、Ken Thompson が、正規表現のサポートを、広く普及したテキスト ユーティリティである qed と grep に組み込みました。Jeffrey Friedl の著書『詳説 正規表現 第 2 版』で詳細に説明されていますので、この本を読み、正規表現の理論的および歴史的な背景を学ぶことをお勧めします。

この 50 年の間に、正規表現は徐々に数学的なあいまいさから脱し、多くのツールおよびソフトウェア パッケージの定番の機能へと進化しました。数十年の間、正規表現は多くの UNIX ツールでサポートされてきましたが、ここ 10 年ほどで、多くの Windows 開発者向けのツールキットでもサポートされるようになりました。Microsoft Visual Basic® 6 や Microsoft VBScript における正規表現の使用はあまり洗練されたものではありませんでしたが、.NET Framework の導入によって、正規表現のサポートはその完成度を増し、すべての Microsoft 開発者とすべての .NET 言語で使用可能になりました。

では、正規表現とはどのようなものでしょうか。正規表現は、テキスト文字列内のパターンを明示的に記述するために使用できる言語です。このようなパターンを単に記述するばかりでなく、正規表現エンジンを使用すると、一般に、一致する対象全体で繰り返す、区切り記号としてパターンを使用して文字列を部分文字列に解析する、高度な方法でテキストの置換または再フォーマットを行うといったことが可能です。正規表現エンジンには、テキスト操作に関連する多くの一般的なタスクを強力かつ通常は非常に簡潔に処理できる機能が備えられています。

正規表現を論じるときに共通するのは、一致するテキストまたは一致しないテキストに基づいて正規表現を分析するという点です。この記事 (および System.Text.RegularExpressions クラス) では、正規表現の "パターン"、"入力" 文字列、および文字列内でパターンが作成するすべての "一致" という、正規表現の操作における 3 つの項目について言及します。

単純な式

正規表現の中で最も単純なものは文字列リテラルで、これは既によく知られています。特定の文字列をそれ自身によってリテラルに記述できます。つまり、"foo" のような正規表現パターンは、入力文字列 foo と正確に 1 回一致します。この場合、"The food was quite tasty" という入力にも一致しますが、完全に一致するものだけを検索する場合、これは望ましくないこともあります。

当然ながら、正確な文字列をそれ自身と一致させることは、ごくありふれた正規表現の使用法で、これでは正規表現機能の能力を発揮できません。"foo" ではなく、"f" で始まるすべての単語、またはこの 3 文字で構成される単語を検索する必要がある場合はどうでしょう。これは、文字列リテラルが無理なく処理できる範囲を超えています。正規表現についてさらに詳しく学ぶ必要があります。リテラル式の例およびそれと一致する入力例を以下に示します。

パターン入力 (一致)
foo foofood、foot、"There's evil afoot."

量指定子

量指定子を使用すると、特定の文字または文字セットの繰り返し回数をパターン内で簡単に指定できます。明示的でない量指定子には次の 3 つがあります。

  1. *: "0 回以上の繰り返し回数" を表します。
  2. +: "1 回以上の繰り返し回数" を表します。
  3. ?: "0 または 1 回の繰り返し回数" を表します。

量指定子は、常に量指定子の直前 (左側) のパターンを参照します。かっこを使用してパターン グループを作成していない限り、量指定子は通常 1 文字です。パターンの例およびそれと一致する入力例を以下に示します。

パターン入力 (一致)
fo* foofoe、food、fooot、"forget it"、funny、puffy
fo+ foofoe、food、foot、"forget it"
fo? foo、foe、food、foot、"forget it"、funny、puffy

? 文字は、指定したパターンが正確に 0 回または 1 回出現することを指定するほか、パターンまたはサブパターンが入力文字列で複数の文字列と一致するときに、最小文字数と一致するように設定します。

明示的でない量指定子 (これは通常、単に量指定子と呼ばれますが、ここでは次のグループと区別します) のほかに、"明示的な" 量指定子もあります。量指定子は、パターンの繰り返し回数についてかなりあいまいですが、明示的な量指定子では、正確な数値、範囲、数値セットを指定できます。明示的な量指定子は、普通の量指定子のように、適用するパターンの後に置かれます。明示的な量指定子は、中かっこ {} と数値を使用して、かっこ内で繰り返し回数の上限と下限を指定します。たとえば、"x{5}" は、5 つの x 文字 (xxxxx) と正確に一致します。1 文字しか指定しない場合、後にカンマを指定 ("x{5,}" など) しなければ、その数値が上限値になります。"x{5,}" と指定すると、5 つ以上のすべての数の x 文字と一致します。パターンの例およびそれと一致する入力例のいくつかを以下に示します。

パターン入力 (一致)
ab{2}c abbc、aaabbccc
ab{,2}c acabcabbc、aabbcc
ab{2,3}c abbcabbbc、aabbcc、aabbbcc

メタ文字

特殊な意味を持つ正規表現内の構成体をメタ文字といいます。*、?、+、{ } 文字などのメタ文字については、既に説明しました。正規表現の言語には、その他にも特殊な意味を持つ文字があります。これらには、$、^、.、[、(、|、)、]、\ などがあります。

. (ピリオドまたはドット) は、最も単純でよく使用されるメタ文字の 1 つで、任意の 1 文字と一致します。これは、特定のパターンに文字の任意の組み合わせを含めるように指定するのに便利です。ただし、この場合、量指定子を使用して一定の長さ範囲に収める必要があります。ここまで、正規表現が、長い文字列内でパターンの任意のインスタンスと一致することを論じてきました。では、パターンと正確に一致させたいだけの場合はどうでしょうか。このようなケースは、ユーザーが入力する文字列が、郵便番号や電話番号の正しい形式になっているかどうかを確認するといった検証シナリオでよく見られます。^ メタ文字は、文字列 (または行) の先頭を指定するのに使用され、$ メタ文字は、文字列 (または行) の末尾を指定するのに使用されます。パターンの先頭と末尾にこれらの文字を追加することで、パターンと正確に一致する入力文字列のみを検索するように設定できます。また、^ メタ文字は、角かっこ [ ] で指定された文字クラスの先頭で使用すると、特殊な意味を持ちます。これらについては以下で説明します。

\ (日本語システムでは円記号 "\") メタ文字は、そのメタ文字の持つ特殊な意味からその文字を "エスケープ" し、あらかじめ定義されたメタ文字のインスタンスを指定するのに使用します。これらについても以下で説明します。正規表現にメタ文字のリテラル バージョンを含めるには、円記号で "エスケープ" する必要があります。したがって、たとえば "c:\" で始まる文字列と一致させる場合は、"^c:\\" と指定します。ここでは、^ メタ文字を使用して、文字列をこのパターンで開始する必要があることを示し、円記号メタ文字でリテラルな円記号をエスケープしたことに注意してください。

| (パイプ) メタ文字は、代替構成体として使用され、実質的にパターン内で "OR 一致" を指定します。したがって、"a|b" のような正規表現は、'a' または 'b' を含む文字列と一致します。これは、文字クラス "[ab]" によく似ています。

また、かっこ "( )" は、パターンをグループ化するのに使用します。これにより、読みやすくする目的でのみ、量指定子を指定してパターン全体が複数回出現できるようにしたり、再フォーマットまたは解析ができるように、入力の特定の部分を個別に一致させることができます。

メタ文字の使用の一例を以下に示します。

パターン入力 (一致)
. abc123
.* Abc123任意の文字列 (一致する文字がない場合も含む)
^c:\\ c:\windowsc:\\\\\c:\foo.txtc:\ (この後には何がきても可)
abc$ abc123abcabc で終わる任意の文字列
(abc){2,3} abcabcabcabcabc

文字クラス

文字クラスは、角かっこ "[ ]" で囲むことで定義される、正規表現内のミニ言語です。最も単純な文字クラスは、"[aeiou]" のような、角かっこで囲まれた単なる文字リストです。式の中で使用すると、パターンのこの位置でこれらの文字のうちいずれか 1 文字を使用できます (量指定子を使用しない場合、使用できるのは 1 文字です)。文字クラスは、単語やパターンの定義には使用できないことに注意してください。定義できるのは、単一の文字のみです。

数字を指定するには、文字クラス "[0123456789]" を使用できます。ただし、このような指定の仕方はすぐに面倒なことになるので、ハイフン文字 "-" を使用することで、かっこ内に文字の範囲を定義するとよいでしょう。ハイフン文字は、正規表現内でなく、文字クラス内で特殊な意味を持ちます (つまり、正確には、ハイフン文字は正規表現のメタ文字として修飾するわけではありません)。また、ハイフン文字は、先頭の文字でない場合に限り、文字クラス内で特別な意味を持ちます。ハイフンを使って数字を指定するには、"[0-9]" を使用します。同様に、小文字の場合は "[a-z]" を使用し、大文字の場合 "[A-Z]" を使用します。ハイフンで定義される範囲は、使用する文字セットに依存します。したがって、ASCII や Unicode テーブルなどに出現する文字の順序によって、範囲にどの文字が含まれるかが決まります。範囲内にハイフンを含める必要がある場合は、それを先頭の文字として指定してください。たとえば、"[-.? ]" は、これら 4 文字のいずれか 1 つに一致します (最後の文字はスペースです)。また、正規表現のメタ文字は、文字クラス内では特殊なものとして扱われないため、エスケープする必要はありません。文字クラスは、規則や構文の点で、他の正規表現とは異なる言語であると考えてください。

また、文字クラス内の最初の文字としてキャラット "^" を使用してクラスを否定することで、文字クラスのメンバを除く任意の文字と一致できます。したがって、母音以外の文字と一致するには、文字クラス "[^aAeEiIoOuU]" を使用できます。ハイフンを否定する場合は、"[^-]" のように、ハイフンを文字クラスの 2 番目の文字に指定します。"^" は、文字クラス内では、正規表現パターンの先頭にある場合とは全く異なる意味を持つことを覚えておいてください。

文字クラスの動作の一例を以下に示します。

パターン入力 (一致)
^b[aeiou]t$ Batbetbitbotbut
^[0-9]{5}$ 11111, 12345, 99999
^c:\\ c:\windowsc:\\\\\c:\foo.txtc:\ (この後には何がきても可)
abc$ abc123abcabc で終わる任意の文字列
(abc){2,3} abcabcabcabcabc
^[^-][0-9]$ 012、 … (-0、-1、-2 などと一致しません)

.NET Framework の次のバージョン (コードネーム "Whidbey") では、文字クラスの削除という新しい機能が文字クラスに追加される予定です。基本的に、この機能では、ある文字クラスを別の文字クラスから削除できます。これにより、より読みやすい方法でいくつかのパターンを記述できます。仕様は、http://www.gotdotnet.com/team/clr/bcl/TechArticles/techarticles/Specs/Regex/CharacterClassSubtraction.doc (英語) で今すぐ入手できます。すべての小文字の子音と一致するには、"[a-z-[aeiou]]" のような構文を指定します。

あらかじめ定義されたメタ文字セット

これまでに説明したツールで実行できることはたくさんあります。しかし、パターン内で数字を指定するたびに "[0-9]" を使用するのでは冗長になり、また、すべての英数字文字に "[0-9a-zA-Z]" を指定するのではさらに冗長になります。これらの頻繁に使用される長いパターンの処理をより簡単にするために、あらかじめ定義されたメタ文字のセットが定義されました。正規表現の実装が異なると、あらかじめ定義されたメタ文字のセットが異なります。ここでは、.NET Framework における System.Text.RegularExpressions API がサポートしているものを使用して説明します。これらのあらかじめ定義されたメタ文字の標準的な構文は、円記号 ("\") とその後に続く 1 つ以上の文字で構成されます。これらの多くは、長さが 1 文字なので、使いやすく、長い文字クラスを置き換えるものとして理想的です。上記の 2 つの例には、任意の数字と一致する "\d" と、任意の単語の文字 (英数字とアンダースコア) と一致する "\w" が挙げられます。例外として、特定の文字コードの一致があります。これには、たとえば、"\u000D" のように、一致する文字のアドレスを指定する必要があります。このアドレスは、Unicode のキャリッジ リターン文字と一致します。よく使用される文字クラスおよびそれに対応するメタ文字のいくつかを以下に示します。

メタ文字対応する文字クラス
\aベル (アラーム) の \u0007 と一致します。
\b文字クラス内にある場合を除き、ワード境界と一致します。この場合、バックスペース文字 の \u0008 と一致します。
\tタブ の \u0009 と一致します。
\rキャリッジ リターンの \u000D と一致します。
\w垂直タブの \u000B と一致します。
\fフォームフィードの \u000C と一致します。
\n改行の \u000A と一致します。
\eエスケープの \u001B と一致します。
\0403 桁の 8 進数で表される ASCII 文字と一致します。\040 は空白 (10 進数の 32) を表します。
\x202 桁の 16 進数で表される ASCII 文字と一致します。この場合、\x2- は空白を表します。
\cCASCII 制御文字と一致します。この場合は ctrl-C です。
\u00204 桁の 16 進数で表される Unicode 文字と一致します。この場合、\u0020 は空白です。
\*あらかじめ定義された文字クラスを表さない文字はすべて、単にその文字として扱われます。したがって、\* は、\x2A と同じ意味になります (* メタ文字ではなく、リテラルの * です)。
\p{name}名前付き文字クラス 'name' の任意の文字と一致します。サポートされる名前は Unicode グループとブロック範囲です。たとえば、Ll、Nd、Z、IsGreek、IsBoxDrawing、Sc (通貨) などを指定できます。
\p{name}名前付き文字クラス 'name' に含まれていないテキストと一致します。
\w任意の単語の文字と一致します。非 Unicode の ECMAScript 実装では、これは "[a-zA-Z_0-9]" と同じです。Unicode カテゴリでは、"[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]" と同じです。
\W\w の否定で、ECMAScript 準拠のセット "[^a-zA-Z_0-9]" または Unicode 文字カテゴリ "[^\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}]" と同じです。
\s任意の空白文字と一致します。Unicode 文字クラス "[\f\n\r\t\v\x85\p{Z}]" と同じです。ECMAScript 準拠の動作が ECMAScript オプションを使用して指定されている場合、\s は、"[ \f\n\r\t\v]" (先頭の空白に注意してください) と同じになります。
\S空白文字以外の任意の文字と一致します。Unicode 文字カテゴリ "[^\f\n\r\t\v\x85\p{Z}]" と同じです。ECMAScript 準拠の動作が ECMAScript オプションを使用して指定されている場合、\S は、"[^ \f\n\r\t\v]" (^ の後の空白に注意してください) と同じです。
\d任意の10 進数と一致します。ECMAScript 動作で、Unicode の "[\p{Nd}]" および非 Unicode の "[0-9]" と同じです。
\D非 10 進数と一致します。ECMAScript 動作で、Unicode の "[\P{Nd}]" および非 Unicode の "[^0-9]" と同じです。

サンプル式

例をあげて説明するのが一番わかりやすいので、ここでサンプル式をいくつか紹介します。http://www.regexlib.com/ Non-MS link に、オンラインの正規表現ライブラリがありますので、参照してください。

パターン説明
^\d{5}$5 桁の数字 (米国の郵便番号など)。
^(\d{5})|(\d{5}-\d{4}$5 桁の数字、または 5 桁-4 桁の数字。これは、米国の郵便番号または米国の郵便番号 + 4 桁の数字という形式と一致します。
^(\d{5}(-\d{4})?$上記と同じですが、こちらの方がより効率的です。? を使用すると、パターンの -4 桁の部分がオプションになり、2 つのパターンを (代替構成体を使用して) 個々に比較する必要がありません。
^[+-]?\d+(\.\d+)?$オプションの記号を持つ任意の実数と一致します。
^[+-]?\d*\.?\d*$上記と同じです。ただし、空の文字列とも一致します。
^(20|21|22|23|[01]\d)[0-5]\d$任意の 24 時制の時間値と一致します。
/\*.*\*/C スタイルのコメント /* … */ の内容と一致します。

ASP.NET での検証

ASP.NET には、検証コントロール スイートが備えられており、Web フォーム上の入力の検証を、レガシ ("Classic") ASP を使用した同じタスクに比べると、はるかに容易に実行できます。強力な検証コントロールのひとつに RegularExpressionValidator があります。このコントロールでは、名前からも推察されるように、入力と一致させる正規表現を指定することで、入力を検証できます。正規表現パターンを指定するには、コントロールの ValidationExpression プロパティを設定します。郵便番号フィールドの検証コントロールの使用例を以下に示します。


<asp:RegularExpressionValidator runat="server" id="ZipCodeValidator" 
ControlToValidate="ZipCodeTextBox" ErrorMessage="無効な郵便番号
形式です。形式は 12345 か 12345-6789 のいずれかでなければなりません。"  
ValidationExpression="(\d{5}(-\d{4})?" />

RegularExpressionValidator に関するいくつかの注意事項

  • 検証するコントロール内の空の文字列によってアクティブになることはありません。RequiredFieldValidator のみが空の文字列をキャッチします。
  • 文字列の先頭と文字列の末尾にマッチング文字 ("^" および "$") を指定する必要はありません。これらのマッチング文字は存在するものと仮定されています。これらのマッチング文字を追加しても、何かが壊れたり変更されるわけではありません。単に必要ないということです。
  • すべての検証コントロール同様、検証はクライアント側とサーバー側の両方で実行されます。正規表現が ECMAScript に準拠していない場合、検証はクライアント上で失敗します。これを回避するには、式が ECMASCript 準拠であることを確認するか、その検証がサーバー上でのみ実行されるようにコントロールを設定します。

正規表現 API

ASP.NET 検証コントロール以外で、.NET の正規表現を使用しているほとんどのケースで、System.Text.RegularExpressions 名前空間にあるクラスを使用します。特に、習得しておく必要がある主要なクラスは、Regex、Match、および MatchCollection です。

ところで、regular expression (正規表現) の省略形 regex を "レグエクス" と読むか、"レジェックス"と読むかについてちょっとした論議があります。筆者の個人的な意見では後者をとりますが、専門家の間では意見が分かれています。どちらでも読みやすい方を選んでください。

Regex クラスには数多くのメソッドおよびプロパティが用意されています。これまで使用した経験がないユーザーは、圧倒されるかもしれません。使用頻度の高いメソッドを以下に示します。

メソッド説明
Escape / Unescape式の中でリテラルとして使用するために、文字列内のメタ文字をエスケープします。
IsMatchregex が入力文字列内に一致を検出した場合、True を返します。
Match入力文字列内で一致が検出された場合、Match オブジェクトを返します。
Matches入力文字列内で検出されたすべての一致を含む MatchCollection オブジェクトを返します。
Replace指定した置換文字列で、入力文字列内の一致を置換します。
Splitregex の一致によって区切られた配列要素に入力文字列を分割することで、文字列の配列を返します。

一般に Regex オブジェクトのコンストラクタには、多くのメソッドの他に、指定可能なオプションも数多く用意されています。これらのオプションはビットマスクの一部なので、OR の組み合わせが可能です (Multiline と Singleline を同時にオンに設定できます。)。

オプション説明
Compiledループ内で多くの一致操作を実行する場合、このオプションを使用します。このオプションを使用すると、各繰り返しで式の解析手順を省くことができます。
Multiline入力文字列内に何行あってもかまいません。"^" および "$" の動作を変更し、入力文字列全体の先頭および末尾ではなく、それぞれ BOL および EOL と一致するようにします。
IgnoreCase検索文字列の一致の際、パターンで大文字と小文字を区別しないことを指定します。
IgnorePatternWhitespaceパターンで必要なだけ空白を保持できるようにし、(?# コメント #) 構文を使用して、パターン内コメントを使用できるようにします。
SingleLine入力文字列内に何行あってもかまいません。ピリオド (".") メタ文字を、既定の \n を除くすべての文字ではなく、すべての文字と一致するようにします。

いくつかの一般的な事項で、検証、一致、置換を含めて正規表現を使用する場合もあります。多くの場合、Regex クラス自身をインスタンス化しなくても、Regex クラスの静的メソッドを使用してこれを達成できます。検証の実行は、単に、正しい式を作成または検索し、それを Regex クラスの IsMatch() メソッドを使用して入力文字に適用するだけで済みます。たとえば、次の関数は、正規表現を使用して郵便番号を検証する方法を示しています。


private void ValidateZipButton_Click(object sender, System.EventArgs e)
{
String ZipRegex = @"^\d{5}$";
if(Regex.IsMatch(ZipTextBox.Text, ZipRegex))
   {
ResultLabel.Text = "郵便番号は有効です!";
   }
else
   {
ResultLabel.Text = "郵便番号が無効です!";
   }
}

同様に、静的メソッド Replace() を使用して、一致した対象を特定の文字列で置き換えることができます。以下にその例を示します。


String newText = Regex.Replace(inputString, pattern, replacementText);

また、次のようなコードを使用すると、入力文字列内で matches コレクション全体を繰り返すことができます。


private void MatchButton_Click(object sender, System.EventArgs e)
{
MatchCollection matches = Regex.Matches(SearchStringTextBox.Text, 
MatchExpressionTextBox.Text);
MatchCountLabel.Text = matches.Count.ToString();
MatchesLabel.Text = "";
foreach(Match match in matches)
   {
MatchesLabel.Text += "Found " + match.ToString() + " at 
position " + match.Index + ".<br>";
   }
}

Regex クラスのインスタンスをインスタンス化する必要が一般的にある場合は、既定の動作以外の動作を指定するときです。特に、オプションの設定がこれに該当します。たとえば、大文字と小文字の違いやパターンの空白を無視する Regex のインスタンスを作成し、その式の一致の対象セットを取得するには、次のようなコードを使用します。


Regex re = new Regex(pattern, 
   RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
MatchCollection mc = re.Matches(inputString);

これらのサンプルの完全動作版は、シンプルな ASP.NET ページ同様、この記事からダウンロードできます。

無料ツール

Regulator (http://royo.is-a-geek.com/iserializable/regulator/ Non-MS link) - クライアント側で実行するために設計された正規表現テスト ツール。このツールは、Web サービスを介して RegexLib と緊密に統合され、Match、Split、Replace などのサポートを提供します。パフォーマンス分析や構文の強調表示機能が含まれています。

RegexDesigner.NET (http://www.sellsbrothers.com/tools/ Non-MS link) - 正規表現の構築およびテストに役立つ強力なビジュアル ツール。C# や VB.NET コードおよびコンパイル済みアセンブリを生成し、式をアプリケーションに組み込むのに役立ちます。

Regular Expression Workbench (v2.0) (http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=C712F2DF-B026-4D58-8961-4EE2729D7322) - Eric Gunnerson が開発した、正規表現の作成、テスト、学習のためのツール。このツールには "Examine-o-matic" 機能が備えられており、正規表現の上にマウスを置くと、その意味を解読できます。

高度なトピック

名前付きグループとルックアラウンド処理という、筆者としては実に考えさせられた 2 つの正規表現機能があります。これらの正規機能はあまり使用されることがないので、ここでは簡単に説明しておくことにします。

名前付きグループを使用する場合、個々の一致グループに名前を付けて、式の中のこれらのグループをプログラムによって参照できます。これは、入力文字列内の要素の順序および配置を変更することで入力文字列を再フォーマットする方法として、Replace メソッドと組み合わせると、強力な機能になります。たとえば、日付を MM/DD/YYYY という文字列形式から DD-MM-YYYY 形式に変更するとします。最初の形式をキャプチャする式を記述し、その Matches コレクション全体を反復し、各文字列を解析し、文字列操作を使用して置換文字列を作成することができます。これには、膨大な量のコードと処理が必要になります。名前付きグループを使用すると、次のようにして同じ処理を実行できます。


String MDYToDMY(String input)
{
return Regex.Replace(intput, @"\b(?<month>\d{1,2})/(?<day>\d{1,2}/(?<year>\d{4})\b", "${day}-
${month}-${year}");
}

また、名前によってだけでなく、数字によってグループを参照することもできます。いずれにしても、このような参照をまとめて "逆参照" と呼びます。また、逆参照は、繰り返し文字を検索するための式 "[a-z]\1" のように、一致式自身の中でよく使用されます。これは、'aa'、'bb'、および 'cc' と一致しますが、"[a-z]{2}" またはこれと同じ意味の "[a-z][a-z]" とは同じではありません。また、'ab'、'ac'、その他の 2 文字の組み合わせも可能です。逆参照を使用すると、既に解析および一致済みの入力文字列の部分について式に記憶させることができます。

"ルックアラウンド処理" とは、多くの正規表現エンジンでサポートしている正および負の先読み (lookahead) および後読み (lookbehind) 機能のことです。ルックアラウンド処理のすべてのバリエーションがすべての正規表現エンジンでサポートされているとは限りません。これらの構成体は、文字と一致しても、文字を使用しません。パターンによっては、ルックアラウンド処理なしには記述できないものもあります。特に、ある部分文字列の有無が別の部分文字列の有無に依存しているパターンは記述できません。各種のルックアラウンドの構文を以下に示します。

構文説明
(?=…)正の lookahead
(?!...)負の lookahead
(?<=…)正の lookbehind
(?<!...)負の lookbehind

ルックアラウンド処理を必要とする例として、パスワードの検証があります。パスワードに 4 ~ 8 文字および最低 1 桁の数字の指定が必要なパスワード制限を考えてみましょう。パスワード検証を実行するには、一致対象に対して "\d" をテストし、長さをテストするために文字列操作を使用します。ただし、正規表現の中の文字全体を検証するには lookahead を使用する必要があります。具体的には、正の lookahead を使用します。式は次のようになります。
^(?=.*\d).{4,8}$

まとめ

正規表現は、テキスト内のパターンを記述するための非常に強力な方法を提供し、これらのパターンを文字列の検証および操作用の優れたリソースにします。.NET Framework は、その System.Text.RegularExpressions 名前空間、具体的にはこの名前空間に存在する Regex クラスにおいて優れた正規表現サポートを提供します。 API の使用はシンプルですが、正しい正規表現を提供するのが困難になることがよくあります。幸いにも、正規表現は広く再利用できます。オンラインに多くのリソースが提供されているので、ここで、他のユーザーが設計した式を探したり、作成が難しい式についてのヒントを得ることができます。

参考資料

正規表現ライブラリ: http://www.regexlib.com/ (英語) Non-MS link

正規表現に関する検討事項の一覧: http://aspadvice.com/login.aspx?ReturnUrl=%2fSignUp%2flist.aspx%3fl%3d68%26c%3d16&l=68&c=16 (英語) Non-MS link

正規表現フォーラム: http://regexadvice.com/forums/ (英語) Non-MS link

正規表現の Web ログ: http://blogs.regexadvice.com/ (英語) Non-MS link

『詳説 正規表現』(O'Reilly)、Jeffrey Friedl 著: http://www.regex.info/ (英語) Non-MS link

.NET 正規表現リファレンス: System.Text.RegularExpressions 名前空間

JScript 正規表現の構文: 正規表現の構文

正規表現に関する情報: http://www.regular-expressions.info/ (英語) Non-MS link

著者紹介

Microsoft ASP.NET MVP の Steven A.Smith は、ASPAlliacne.com および DevAdvice.com の代表兼オーナーであると同時に、.NET に特化した研修会社である ASPSmith Ltd のオーナー兼ヘッド インストラクタでもあります。Steve は、『ASP.NET Developer's Cookbook』と『ASP.NET By Example』の著者であり、MSDN および AspNetPRO マガジンにおいても多くの記事を執筆しています。また、毎年いくつかのカンファレンスで講演し、INETA 講演者事務局のメンバでもあります。Steve は、経営管理学の修士号、およびコンピュータ サイエンス エンジニアリングの理学士号を取得しています。

Steve の電子メール アドレスは ssmith@aspalliance.com です。


表示: