^(?<first>.{6})(?<last>.{8})(?<city>.+)$ |
「ドット(.)」は、「任意の文字」表す。すなわち、「.{6}」は、「任意の6文字」である。
「(?<first>.{6})」という式は、最初の6文字と一致する「first」という名前のグループを作る。同様に「(?<last>.{8})」という式は、次の8文字と一致する「last」という名前のグループを作る。最後の「(?<city>.+)」という式は、残った行末部分までの文字をグループ化した「city」という名前のグループを作る。「^」と「$」という文字は、それぞれ、「行頭」と「行末」だ。
ファイルをパースするには、VBやC#を使って、この正規表現を使った短いルーチンを書ける(リスト1は、ここからダウンロードできる)。
下記のVB.NETおよびC#のコードは、正規表現を使って固定長のテキストファイルをどのようにパースするかを示した断片的なものだ。カンマ区切りテキストファイル(ダブルクォーテーションによってクォートされたものも含む)をパースするには、正規表現のパターン部分を編集すれば良く、その他のステートメントを変更する必要はない。
リスト1■VB.NET、C#でテキストファイルをパースするスマートな方法 |
' VB.NET Dim sr As New StreamReader("c:\data.txt") Dim pattern As String = _ "^(?<first>.{6})(?<last>.{8})(?<city>.+)$" Dim re As New Regex(pattern) Do While sr.Peek <> -1 Dim ma As Match = re.Match(sr.ReadLine()) Console.Write("First name = " & _ ma.Groups("first").Value.TrimEnd()) Console.Write(", Last name = " & _ ma.Groups("last").Value.TrimEnd()) Console.WriteLine(", City= " & _ ma.Groups("city").Value.TrimEnd()) Loop sr.Close() // C# StreamReader sr = new StreamReader("c:\\data.txt"); string pattern = @"^(?<first>.{6})(?<last>.{8})(?<city>.+)$"; Regex re = new Regex(pattern); while ( sr.Peek != -1 ) { Match ma = re.Match(sr.ReadLine()); Console.Write("First name = " + ma.Groups["first"].Value.TrimEnd()); Console.Write(", Last name = " + ma.Groups["last"].Value.TrimEnd()); Console.WriteLine(", City= " + ma.Groups["city"].Value.TrimEnd()); } sr.Close(); |
正規表現に基づいたこのアプローチの美しいところは、フィールド長や区切り記号(デリミタ)が変わっても、それに対応させるのが信じられないほど容易という点だ。
たとえば、固定長フィールドがセミコロンで区切られる場合、コードを変更することなく、次のように正規表現を修正すればよい。
^(?<first>.{6});(?<last>.{8});(?<city>.+)$ |
いちど正規表現の動きを理解してしまえば、パーサールーチンの作成や修正は、まるで子供の遊びのように簡単になってしまうだろう。――Francesco Balena
さて、ほかのアプリケーションとのデータ交換に主として使われている「区切り記号で区切られたテキストファイル」をパースするプログラムを書きたいとしよう。
フィールドは、それぞれ、「カンマ」「セミコロン」「タブ」や、その他の特殊記号によって分割される。さらに自体が複雑なのは、そのようなファイルには、シングルクォート(')やダブルクォート(")が値に含まれることを許すという点だ。
この時、パースするためにStringクラスのSplitメソッドを使うことはできない。なぜなら、クォートされた値が、「"Doe,John"」のように、区切り記号を含んでいるならば、正しい結果とならないからだ。
正規表現は、まさにそのような時の救い主だ。
© Copyright 2001-2005 Fawcette Technical Publications