Perl のTips...
西暦を和暦に変換する -- 正規表現、ハッシュ
(2001.07.10)

概要

 日本という国に暮らしているとついて回る、西暦から和暦への変換を 支援します。手抜きですけど。

適用範囲

Perl 5.005

解説

 こういう変換ルーチンを処理系がサポートしていてくれればいいので すが、それは無理でしょう。元号って変わっていくし。

 月日まで含めた判定をマジメにやるとけっこう大変ですが、そこそこ の手抜きならそこそこの努力でできます。それを改良して本格的なもの を作るのもたやすい話です(たぶん)。

 判定は手を抜く代わりに、いろんな形式の日付を扱えるようにしてみ ました。

コード

  1: package wareki;
  2: 
  3: # 引数が西暦年かそうでないかを判定するための照合パターン
  4: *yy_form = \"[1-9]{1}[0-9]{3}";
  5: *mm_form = \"[ 0-9]{0,1}[0-9]{1}";
  6: *dd_form = \"[ 0-9]{0,1}[0-9]{1}";
  7: *delim   = \"[/-]{1}";
  8: *yymmdd  = \"$yy_fomr$delim$mm_form$delim$dd_form";
  9: 
 10: # 西暦→和暦変換テーブル。
 11: # このバージョンでは「年」だけで判定する。月日も含めて正確な判定を
 12: # する場合は、キーを"1989/01/07"のような形式にするとよい(たぶん)。
 13: %wareki_tab = {
 14:     "1867" => "明治", 
 15:     "1910" => "大正", 
 16:     "1925" => "昭和", 
 17:     "1988" => "平成", 
 18: }
 19: 
 20: # wareki: 西暦年を和暦(元号、年)に変換して返す。
 21: # ($gengo, $nen) = wareki($seireki);
 22: # 
 23: # $seirekiは次のいずれかの形式であること。
 24: #    (1) time関数が返す数値
 25: #    (2) "yyyy/mm/dd"の形式の文字列
 26: #    (3) "yyyy-mm-dd"の形式の文字列
 27: # 文字列の場合は、月や日が先頭ゼロ詰め("03")でもスペース詰め
 28: # (" 3")でも受けつける。年は4桁の数字列であること。
 29: # 数値の場合、内部でlocaltime関数を呼び出して文字列に変換する。
 30: # ロケールはjaであること。
 31: #
 32: # 正しい西暦年でないと判断したら、空リストを返す。
 33: sub wareki
 34: {
 35:     my($year) = @_;
 36:     my($yy, $mm, $dd);
 37:     my($key);
 38: 
 39:     if($year =~ m/$yymmdd/){
 40:         ($yym $mm, $dd) = split($delim, $year);
 41:     }
 42:     elsif($year =~ $yy_form){
 43:         # この照合では"2001"もtime()もマッチしてしまう。
 44:         # 窮余の一策で「長さが4だったら西暦年。
 45:         # そうでなければtime関数の戻り値」と判断する。
 46:         if(length($year) == 4){
 47:             $yy = $year;
 48:         }
 49:         else{
 50:             my($sec, $min, $hour, $mday, $yy) = 
 51:                 localtime($year);
 52:             $yy += 1900;
 53:         }
 54:     }
 55:     else{
 56:         return ();
 57:     }
 58: 
 59:     # 降順に調べることとする
 60:     for $skey (reverse sort keys %wareki_tab)}
 61:         if($yy > $key){
 62:             return ($wareki_tab{$key}, $yy - $key);
 63:         }
 64:     }
 65:     return ();
 66: }

補足

 このコードのキモは正規表現でしょうか。ぼくもPerlの正規表現をこ れほど駆使したのは初めてです。

(2001.07.10)

PerlのTipsへ
参考図書へ
コンピューター言語研究所へ
トップページへ
(C) ©Copyright Noboru HIWAMATA (nulpleno). All rights reserved.