少し前、Twitter 等で内閣府の国民の祝日csvが酷いという話が話題になりましたが、今ではとてもプログラマに優しいフォーマットになってますので、PHP を使って 3 行で処理してみます。
コード
//-- csvを取得
$csv = file_get_contents('https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv');
//-- UTF8へ変換
$csv = mb_convert_encoding($csv, 'UTF-8', 'SJIS-win');
//-- 正規表現で抜き出す
if (!preg_match_all('/(\d{4})\/(\d{1,2})\/(\d{1,2}),(.+)/u', $csv, $matchAllAry, PREG_SET_ORDER)) {
die('Error');
}
コメントまで含めると 10 行になっちゃってますが、コード的には実質 3 行です。
この後どうするの?
preg_match_all()
の第 4 引数に PREG_SET_ORDER
を渡す事により、$matchAllAry
は foreach
で処理しやすい配列になっていますので…
配列にしてみるとか…
$holidayAry = [];
foreach ($matchAllAry as $matchAry) {
list( , $year, $month, $day, $name) = $matchAry;
$tmpAry = [
$year,
sprintf('%02d', $month),
sprintf('%02d', $day),
];
$holidayAry[$year][implode('/', $tmpAry)] = trim($name);
//-- 場合によってはこんな配列にしてしまうとか
// $holidayAry[(int) $year][(int) $month][(int) $day] = trim($name);
}
print_r($holidayAry);
//-- serialize()して保存すれば、簡単に配列として再利用する事もできます
file_put_contents('./holiday.array', serialize($holidayAry));
print_r(unserialize(file_get_contents('./holiday.array')));
フォーマットを変換してみるとか…
$tsv = '';
foreach ($matchAllAry as $matchAry) {
list( , $year, $month, $day, $name) = $matchAry;
$tmpAry = [
$year,
sprintf('%02d', $month),
sprintf('%02d', $day),
trim($name),
];
$tsv .= implode("\t", $tmpAry) . "\n";
}
echo $tsv;
初心者の方は、祝日に対応した万年カレンダー辺りを作ってみたら、色々と勉強になるのではないでしょうか。
余談
- 祝日のデータを○○の形式に変換したものが欲しい
- なにか csv でも無いかな?とググる
- PHP でコードを書いて実行
今回のような処理なら、↓のような環境を作っておけば、ほんの数分で欲しい結果が得られます。
こういう「手軽さ」も、スクリプト言語の良いところですので、IDE とは別に環境を用意しておくと、何かと便利ですよ。
なお、これまで「正規表現を使うのは最終手段した方が良いです」と何度か書いていますが、今回のように「その場で欲しい結果がサクっと得られさえすればそれで OK」というケースなら、正規表現でも別に良いと思います。
使い分けが大事ですね。