NasupiiのPerl書抜帳
MS-Excelからのデータ取り込み時のデータ整形プログラムソースコード
Perl ソースコード
# ================================================================================
# 評価用に付けたメインプログラム
# Copyright (C) 2013 Nasupii
# ================================================================================
$FNAME_I = "Book1.txt"; # 入力ファイル名
$FNAME_O = "book1x.txt"; # 出力ファイル名
open(IN, "< $FNAME_I");
$buf = "";
while( $line = <IN>) {
$buf .= $line;
}
close(IN);
print "\n=====元データ======================\n",$buf;
tr_tabtxt($buf);
print "\n=====変換後データ==================\n",$buf;
open(OUT, "> $FNAME_O");
print OUT $buf;
close(OUT);
exit;
# ================================================================================
# sub tr_tabtxt
# MS-Excelからデータをタブ区切りテキストファイルで出力し
# perlプログラムで取り込むとき問題になる事項を解消する
# このサブプログラムは Shift-JIS 専用とする
# Copyright (C) 2013 Nasupii
# 2013/02/11 初版作成
# 使い方
# 1.メインプログラムでタブ区切りテキストファイルを1つの文字列に読み込む。
# 2.読み込んだ文字列を引き数として、このサブルーチンを呼ぶ。
# 3.引数の文字列が置き換えられれメインルーチンに戻る。
# ================================================================================
# a.セル内に改行がある場合
# 改行を含むセルは、セルの始まりと終わりに " がついて、
# 改行はそのまま出力される。Excelでは1行だったものが複数行になる
# ので、正しく読み込めない不具合がある。
# そこで、セル内の改行はシフトJISで割り当てられていない 0xfeに
# いったん置き換えし、余分についた " を削除したのち、0xfe を
# $NL で指定した文字に再度置き換える。
# この例では、_| に置き換えている。
# b.セル内に , (カンマ)が入っている場合
# , (カンマ)を含むセルは、セルの始まりと終わりに " がついて、
# カンマはそのまま出力される。
# そこで、余分についた " を削除する。
# c.セル内に " (二重引用符)が入っている場合
# " を含むセルは、セルの始まりと終わりに " がついて、
# "は連続する2この""として出力される。
# そこで、連続する2この " をシフトJISで割り当てられていない 0xfdに
# いったん置き換えし、余分な " を削除したのち 0xfd を " に戻す。
# ================================================================================
sub tr_tabtxt {
my($NL, $fd, $fe);
# ====== 初期設定 ======
$NL = "_| "; # セル内の改行を置き換える文字
$fd = chr(0xfd);
$fe = chr(0xfe);
# セル内の""を0xfdに置き換え
# \A:文字列の先頭 \t:タブ \n:改行 \Z:文字列の終端
$_[0] =~ s/([^\A\t\n])""([^\Z\t\n])/\1$fd\2/gmo;
$_[0] =~ s/([^\A\t\n])""([^\Z\t\n])/\1$fd\2/gmo;
# セル内の \n(改行)を0xfeに置き換え
do {} while($_[0] =~ s/(\A|\t|\n)"([^"\n]*)\n([^"]*)"(\Z|\t|\n)/\1"\2$fe\3"\4/gm);
# セルの始まりの"を削除
$_[0] =~ s/(\A|\t|\n)"/\1/gm;
# セルの終わりの"を削除
$_[0] =~ s/"(\Z|\t|\n)/\1/gm;
#0xfd を " に置き換え
$_[0] =~ s/$fd/"/gm;
#0xfe を $NL に置き換え
$_[0] =~ s/$fe/$NL/gm;
return();
}