パターンマッチ処理

与えられたデータを自動的に処理するプログラムの必要性と有用性は高い。 そのことを見越して、自動処理しやすい形式でデータファイルを 作成しておくことが重要である。 また,Webページのアクセスログなど,計算機が自動的に生成する ログファイルは,テキスト形式で書き出されるものが多い。 テキストファイルからから統計的な処理に必要な情報を抜き出すためには

テキストを処理するプログラムは,その入力パターンに応じて処理を 決定する。入力パターンの照合は対象となるの書式を元に決める。

カンマ「,」やタブ文字などの特定文字列による分解(例: csvファイル)

splitメソッドで分解

特定キーワードで分解

正規表現を用いて解析

splitによる処理

ある特定の文字でフィールドを区切られている書式(DSV; Delimiter-Separated Value)で,フィールド値に区切り文字が現れないようなものは split で簡単に解析できる。csvファイルの処理例を示す。

yamagata.csvは, 文字列もクォートなしで書かれたcsvファイルで,

第6フィールド市町村名
第9フィールド総人口
第10フィールド男人口
第11フィールド女人口

となっている。これを split で分解して, 市町村と総人口のみの集計出力を得るには以下のようにする。

#!/usr/bin/env ruby
# coding: euc-jp
while line=gets
  data = line.chomp.split(",")
  printf("%-20s%s\n", data[5], data[8])
end

正規表現を用いた処理

固定区切りでないものは正規表現でパターンマッチを行ない, 後方参照を用いてマッチした一部を取り出す。

電子メイルのファイルから差出人を抽出してみる。 差出人はメイルヘッダの Return-path か,From の値から取得する。電子メイルのヘッダは,1行目から始まり,空行で終わる。 行頭(先頭カラム)から始まり,コロンまでのものがフィールド名, その後ろがフィールド値である。

メイルのヘッダ部分のみを繰り返す処理は,

while line=gets
  break if /^$/ =~ line    # 行頭(^)の直後に行末($)で空行を表すパターン
  〜処理〜
end

のように書ける。この間で,Return-pathまたは Fromを得る処理は以下のようにする。

while line=gets
  break if /^$/ =~ line
  if /^(return-path|from): *(.*)/i =~ then
    from = $1
  end
end

これを応用して,1通のメッセージを含むファイルから差出人などの 情報をサマリ表示するプログラムを作ると以下のようになる。

headervalue.rb

#!/usr/bin/env ruby
# coding: euc-jp
# Parse rfc2822 header and display summary

while line=gets
  break if /^$/ =~ line
  if /^(return-path|from): *(.*)/i =~ line then
    from = $2
  elsif /^subject: (.*)/i =~ line then
    subj = $1
  elsif /^date: (.*)/i =~ line then
    date = $1
  end
end

printf("%s: %sさんからの「%s」というメイルです。\n", date, from, subj)

この例では,Return-Path と From に加え,サブジェクトを保持する Subject ヘッダと,日付けを保持する Date ヘッダの値をそれぞれ取得している。


本日の目次

yuuji@e.koeki-u.ac.jp