はじめに
正規表現(Regular Expression)とは、コマンドプロンプトのワイルドカードのように、テキストを解析して特定の処理をする機能です。正規表現は便利で強力な反面、パターンと呼ばれる記号と文字列の組み合わせ方法を学習する必要があるため、最初は難しく感じることがあります。そこで、本稿では「RegexDesigner.NET」という正規表現のパターンを簡単にテストできるフリーウェアを使いながら例を紹介していきます。
正規表現は、Perl/Rubyといった言語や、Unix系のツールで利用するものと思われがちですが、.NETにおいても同様に高度な機能を使うことができますので、正規表現をマスターして高度なテキスト処理(マッチング、抽出、置換)を行ってみましょう。
対象読者
Visual Studio(.NET)にて開発を行っていて、.NETの正規表現に興味がある方を対象としています。
ダウンロードファイルの概要
ダウンロードファイルを解凍すると、「RegexDesigner.NET」のプロジェクトファイルが複数含まれています。このプロジェクトファイルを順に開いて、正規表現のパターンをテストしてみてください(RegexDesigner.NETの入手方法や使用方法については後述)。
また、正規表現を利用したサンプルプログラムも添付しています。必要に応じてVisual Studioからソースコードを開いて確認してください。
必要な環境
ダウンロードファイルに含まれる、RegexDesigner.NETのプロジェクトファイルはRegexDesigner.NETのバージョン1.1にて作成しています。
サンプルプログラムはVisual Studio 2003にて作成しています。本文中はC#にて解説していますが、ダウンロードファイルはVisual Basic.NET版も用意しています。また、Visual C#(Visual Basic)2005 Express Editionでも動かすことができます(最初にプロジェクトをアップグレードするウィザードが表示されます)。
正規表現とは
正規表現は、テキストを解析してマッチング、抽出、置換といった処理をすることができる機能です。コマンドプロンプトのワイルドカード(*.txt)や、SQLのLIKE
句(LIKE 'A%'
)の高機能版とイメージすると分かりやすいでしょう。
正規表現でできること
正規表現では、大きく次の3つの用途で利用することができます。
- 特定の文字列と一致するかをチェックする
- 特定の文字列を抽出・置換する
- 特定の文字列で分割する
例えば、入力された郵便番号が正しいかをチェックしたり、サーバーログから特定の条件のメッセージだけを抽出したりできます。プログラムを書いても同様の処理ができますが、正規表現を利用した方がプログラミングの量を減らせることが多いため、バグの軽減に役立ちます。
正規表現のコード例
正規表現のメリットを理解するために、郵便番号をチェックするC#のコード例を見てみましょう。下のコードは、正規表現を使わずに郵便番号が「999-9999」形式になっているかをチェックしています。
//チェックする郵便番号 string input = "123-4567"; //文字数をチェック if (input.Length == 8) { //文字列をcharの配列に char[] c = input.ToCharArray(); //文字数回ループ for( int i = 0; i < 8; i++) { if (i == 3) { //4文字目はハイフンのはず if (c[i] != '-') { return; } }else{ //それ以外は数字のはず if (! char.IsDigit(c[i])) { return; } } } MessageBox.Show("正しい郵便番号"); }
それほど難しい処理をしているわけではありませんが、ループやif
文が多いため、こういったフォーマットのチェックは思いのほか面倒です。続いて、正規表現を使ったコードを見てみましょう。
//正規表現のパターン Regex regex = new Regex(@"^\d{3}-\d{4}$"); //郵便番号のチェック if( regex.IsMatch("123-4567") ) { MessageBox.Show("正しい郵便番号"); }
「^\d{3}-\d{4}$
」という正規表現特有のパターン文字列がある以外には、難しいところはないと思います。このように正規表現を利用すれば、短いコード量でテキスト処理を容易にできるようになります。
また、正規表現を使うと保守性もよくなります。もし郵便番号のフォーマットで「999」や「999-99」も正しいことに変更するとしても、パターン文字列を「^\d{3}(-(\d{4}|\d{2}))?$
」に変更するだけで済みます。