伊藤清徳の垂直落下式ムーンサルトプレス

PerlとかPHPとかMySQLとか…がんばっても8割だ。
10月 14
PerlでCSVを扱う
icon1 admin | icon2 perl, 未分類 | icon4 10 14th, 2009| icon3No Comments »

PerlでCSVを読み込むメモ。

これまで私は、
こちらのサイトを参考に正規表現だけで処理していました。

速度が云々あるでしょうけれど、そもそもそんなに速度が気になるのならCSVじゃないデータを使うべきでしょう。ということで、これだけで十分です。

※なお、CSVデータは完全にアプリケーション依存のデータフォーマットで入出力するアプリケーションによって形式が異なります。この記事ではMS-AccessのCSVを前提に書きます。エクセルも問題ないと思います。それ以外のアプリケーションでの動作は考慮していませんので、必要に応じて書き換えて使ってください。



ですが、CPANのモジュールも活かさないとそれはそれでもったいないので、今回はそちらを使ったときのメモ。

いくつかのモジュールがあり、中には数々の文字コードのCSVの処理を考慮したものもありますが、エクセルでの出力で最も多いであろうShift-JISのデータを扱うには、Text::CSVをバイナリモードで使うのが一番トラブルが少ないようです。

じゃぁやってみよう!

use strict;
use Text::CSV;
use IO::File;


#CSVファイルを開きます。
my $file = "CSVのパス";
my $io = IO::File->new( $file, 'r' );

#解析をはじめましょう。
my $csv = Text::CSV->new({binary => 1});
while (not $io->eof and my $columns = $csv->getline($io)) {
    #ここでデータを処理する。
    #$columnsへ1レコード分のデータが配列への参照として渡されます。
    #例:$columns->[0](1列目)
}
exit();

こんな感じ。意外にベタベタと書かないといけない。
Text::CSVは標準モジュールではないので、インストールが必要なことを忘れずに。



ちなみに、Text::CSV::Simpleというモジュールもありまして、こちらを使うと、全CSVのデータを一気に二次元配列として処理してくれます。さすがにこれはデータ量を考えないとアレですが、便利は便利です。合わせて覚えておきたいです。

7月 22

とても面倒な日付・時刻計算をPerlで行うためのCPANライブラリ。
それがDate::Calc。

調べたら、なんだか直訳調っぽくて「何言ってんだか?」みたいなとこしかなかったので、
今回使った部分だけメモ。

use strict;
use Date::Calc qw(:all);
 
#UNIXタイムスタンプの取得
my $time = Mktime( 2009, 6, 5, 12, 42, 44); 
print $time . "n";

#今の時間を取得
my ($year,$month,$day, $hour,$min,$sec) = Today_and_Now();
print "$year年$month月$day日 $hour時$min分$sec秒n";
#日付のみ取得 ($year,$month,$day) = Today(); 
#時刻のみ取得 ($hour,$min,$sec) = Now();
 
#2008年6月1の30日前の日付を計算
($year,$month,$day, $hour,$min,$sec) = Add_Delta_DHMS( 2008, 6, 1, 0, 0, 0, -30, 0, 0, 0); 
print "$year年$month月$day日 $hour時$min分$sec秒n";
#引数
#[0]:基準の年 [1]:基準の月 [2]:基準の日
#[3]:基準の時 [4]:基準の分 [5]:基準の秒
#[6]:何日後(前はマイナス指定)を計算するか
#[7]:何時間後(前はマイナス指定)を計算するか
#[8]:何分後(前はマイナス指定)を計算するか
#[9]:何秒後(前はマイナス指定)を計算するか

#今を基準にして10日後の3時間15分30秒前を計算
($year,$month,$day, $hour,$min,$sec) = Add_Delta_DHMS( Today_and_Now() , 10, -3, -15, -30); 
print "$year年$month月$day日 $hour時$min分$sec秒n";
#第6引数まではToday_and_Now()を使える。
#日付のみの計算 ($year,$month,$day) = Add_Delta_YM($year,$month,$day, $Dy,$Dm);
#時刻のみの計算 ($year,$month,$day) = Add_Delta_YMD($year,$month,$day, $Dy,$Dm,$Dd); #日付のみの計算 ($year,$month,$day) = Add_Delta_YMD($year,$month,$day, $Dy,$Dm,$Dd);
#時刻のみの計算 (

#日付として正しいか?(リターンは1または0)
#↓不正
print check_date( 2009, 13, 1 ) . "n";
#↓正常
print check_date( 2009, 12, 31 ) . "n";

#時刻として正しいか?(リターンは1または0)
#↓不正
print check_time( 26, 12, 62 ) . "n";
#↓正常
print check_time( 23, 59, 59 ) . "n";

よく使いそうなところはこんなもん?

【一応メモ】
競合する関数名の関数を自分で作っているときは、競合してしまうので、
use Date::Calc qw(:all);

use Date::Calc;
に変更して、関数にDate::Calc::をつけて関数実行。

【すみません】
誤りがありました。日付の増減計算はありましたが、時刻のみの増減計算はありませんでした。修正しました。

7月 9
PerlでSwitch
icon1 admin | icon2 perl | icon4 07 9th, 2009| icon3No Comments »

個人的備忘録

Perlで複数分岐がif{}elsif{}else{}しかないのが不便だなー

Switch文使えないかなー

とか思ってたら、Switchというモジュールがあることを知った。

すげぇ。PerlでSwitch使えるじゃん!って思った。そしたら、5.8.0から標準モジュールだったんですね。

知らなかった。情けない(>_<)

ちなみにAcme::Commentモジュールを使うと、Cの/*—*/スタイルの複数行コメントが使えるよ。まぁ=pod — =cutスタイルで十分だけど。

6月 9

先日、クライアントさまより、UTFのとき全角ハイフンがおかしくなるよ!と連絡。

そ・・・そんなはずは(-_-;)、と思って調べたら本当でした。

その対策方法をメモメモ。

どうも、Jcode.pmのtrを使って

全角マイナス記号「-」(コードでは、\xE2\x88\x92)
(※見た目はよく似ているけど、ハイフンでもないし、ダッシュでもないので注意。)
を半角記号へ変換するときに、
半角チルダ「~」になっちゃったり、
\x3Fという通常の環境で見ることができないコードに変換されている模様。

ってことで、Jcodeでtrしたあと、これらを無理やり「-」(コード\x2D)に変換することで対応。
本当にチルダが来たときどうすんだ!?という感じ。

だったので、さらに調べたら、

http://d.hatena.ne.jp/littlebuddha/20081121/1227241729

こちらのサイトにまとめがありました。のでまぁこの通り設定。
全角の扱いって難しいですね。

何か調べたら同じハイフンでも、
「ハイフン」「ノンブレーキングハイフン」「ハイフネーションポイント」…などなどあるんですって。
文系出身ダメプログラマーな私にはグルグルする話です。。。

PHPのmb関数でも同様の問題がおきます。
ので、ハイフンに見える文字についての知識はUTFを扱うときは必ず身につけておく必要がありそうです。

6月 26

WindowsでPerlならActivePerlだよなと漠然と考えていたが、こんな情報が!


MOONGIFTのStrawBerryPerlの情報ページ

早速使ってみたけど、普通にPerlとして使えるし、
CPANモジュールインストールしてみたけど、
X系OSと変わらないインストールができる!!
しかもPPMも普通に使えるらしい!
今度からこっちをインストールすべきだ!!

個人的には、PDKとか使ってるので全面移行はできないけど。。。
PDKのPerlSvcとかは激しく便利。。。

6月 25

長いタイトル・・・。

use Data::Dumper;
my $str = 'ABC';
my $jhan =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
. "0123456789!\"#\$%&'*+,./:;<=>?\@[\\]^_`{|}~-";

my $jzen = “abcdefghijklmnopqrstuvwxyz”
. “ABCDEFGHIJKLMNOPQRSTUVWXYZ”
. “0123456789”
. “!”#$%&’*+,./:;<=>?@[¥]^_‘{|}~-”;

my $j = Jcode->new();
$j->set( $str , ‘euc’ );
my $convert = $j->tr( $jzen , $jhan );
とかして$convertをDumper()にかけると

素直に変換された文字列がdumper()されるわけじゃなく、

Jcodeにblessされたという内容が書き出される。

この値をファイルに保存したときにゃあ(>_<。)

スマートじゃないけど、

$convert = “” . $convert;

って書き加えたほうが良さげ。

6月 19

ActivePerl使うと、ファイルオープンな感覚でCOMポートから流れてくる文字を受け取れるらしい。

#!C:/Perl/bin/perl.exe -w  use strict;  open( my $port , "+>COM3" ) || die "Can't open COM3: $!"; while(){   my $serial = $port;   print $serial; }  __END__

こんな感じ。
マルチスレッドとかにして、ファイルハンドルをフックすれば使えるアプリができるかも??

 ANZXCvg