blog20100901

2013/08/20 - プログラミング言語 Perl にまつわる etc. - Perl monger
参考 : perldoc, perldoc.jp, search.cpan.org, perldoc.perl.org ...
「 初めての Perl 第 6 版 」(オライリー・ジャパン発行 ISBN978-4-87311-567-2) 」
「 続・初めての Perl 改訂版 」(オライリー・ジャパン発行 ISBN4-87311-305-9) 」
「 Effective Perl 第 2 版 」(翔泳社発行 ISBN978-4-7981-3981-4) 」 ... etc,.

Perl Perl_1

Perl 「 モジュール 」 ( 割り込み ) Text::CSV_XS メソッド fileds() (0xb9)

Perl 「 モジュール 」 ( 割り込み ) Text::CSV_XS メソッド fileds() (0xb9)

目次 - Perl Index


Theme



Perl について、復習を兼ねて断片的な情報を掲載して行く連載その 0xb9 回。

Perl モジュール Text::CSV_XS による CSV データ加工に必要なメソッド fields() を割り込み ( interrupt ) で確認する。



Perl 「 モジュール 」 ( 割り込み ) Text::CSV_XS インストール (0xb7)
Perl 「 モジュール 」 ( 割り込み ) Text::CSV_XS メソッド parse() (0xb8)


利用方法の参考 Web サイト



前々回にユーザのローカル領域にインストールした Perl モジュール Text::CSV_XS を実際に利用して、CSV ( カンマ区切り ) のデータを処理します。

利用方法は引き続き以下のページを参考にします。

Text::CSV_XS - perldoc.jp

perl - CSVはText::CSV(_XS)?で - 404 Blog Not Found


メソッド parse() の動作を振り返る



英語の「 parse 」には、「 文を文法的に解析する 」や「 構文解析 」という意味がありますが、Text::CSV_XS のメソッド parse() は、CSV 形式のデータを ( おそらく RFC 4180 に従い ) 構文解析し、 適切なフィールド群を生成する機能を提供します。

Perl デバッガを利用して確認したところ、1 度 parse() で処理したデータは、オブジェクトの中に次の様に格納されていました。

CSV 形式から分割された値が「 '_FIELDS' => ARRAY(0xd63ad8) 」に、CSV 形式のままの値が「 '_STRING' => SCALAR(0xc43ea8) 」に格納されています。


DB<2> x \$csv
0 REF(0x81eab8)
-> Text::CSV_XS=HASH(0xe59f58)
'_AHEAD' => undef
'_BOUND_COLUMNS' => undef
'_CACHE' => "\"\",\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\c@\cA\c@\c@\c@\c@\c@\cA\cA\c@\c@\cA\c@\c@\c@\c@"
'_COLUMN_NAMES' => undef
'_EOF' => ''
'_ERROR_INPUT' => undef
'_FFLAGS' => ARRAY(0xcd8958)
empty array
'_FIELDS' => ARRAY(0xd63ad8)
0 '1_foo'
1 'bar'
2 'baz0,baz1'
3 'qux'
4 'quux'
'_RECNO' => 1
'_STATUS' => 1
'_STRING' => SCALAR(0xc43ea8)
-> '1_foo,bar,"baz0,baz1",qux,quux
'
'allow_loose_escapes' => 0
'allow_loose_quotes' => 0
'allow_unquoted_escape' => 0
'allow_whitespace' => 0
'always_quote' => 0
'auto_diag' => 0
'binary' => 0
'blank_is_undef' => 0
'callbacks' => undef
'decode_utf8' => 1
'diag_verbose' => 0
'empty_is_undef' => 0
'eol' => ''
'escape_char' => '"'
'keep_meta_info' => 0
'quote_binary' => 1
'quote_char' => '"'
'quote_null' => 1
'quote_space' => 1
'sep_char' => ','
'types' => undef
'verbatim' => 0




メソッド fields() と combine() それと string()



fields() は、parse() のパース ( 構文解析 ) によって「 CSV で分割 」されたフィールドを取得するメソッドですが、もうひとつ combine() というメソッドが処理した「 CSV で連結 」されたデータのも取得することも出来ます。

しかしながら、通常 combine() が CSV で連結したデータは、メソッド string() を利用してスカラデータとして取得するはずです。なぜなら、combine() の役割は「 連結 」だからです。

仮に combine() で処理したデータを fields() で取得した場合、結果としてそれは、parse() によって「 CSV で分割 」されたデータと同じものです。


my $csv = Text::CSV_XS->new; # オブジェクト作成
while(<>) {

$csv->parse($_); # parse で処理
my @arry = $csv->fields(); # fields で取得
print "parse : @arry\n";

$csv->combine(@arry); # combine で処理
my $string = $csv->string(); # string で取得
print "combine: $string\n";

my @string = $csv->fields(); # combine の処理を fields で取得
print "cmb,fil: @string\n";
}


実行結果は次の通りです。


parse : 1_foo bar baz0,baz1 qux quux
combine: 1_foo,bar,"baz0,baz1",qux,quux
cmb,fil: 1_foo bar baz0,baz1 qux quux


「 parse 」の出力は、parse() で処理した CSV 形式の文字列データを、fields() で取り出したものです。フィールド毎に配列 @arry の要素となっていることが分かります。

「 combine 」の出力は、parse() の処理によりリストデータ化された文字列を、combine() で処理し、再び CSV 形式のデータとして連結したものです。

string() によって取り出されるデータは、複数のフィールドからなるリストデータではなく、combine() によって単一の文字列データとされているため、スカラ変数で受け取っています。

「 cmb,fil 」の出力は、combine() で処理したはずのデータを、fields() によって取り出したものです。 これは最初の「 parse 」の出力と同じデータであることが分かります。

ちなみに、parse() で処理したデータを、string() で取り出した場合は、「 combine 」の出力と同じデータが得られます。

これはおそらく、Perl デバッガで確認した Text::CSV_XS オブジェクトのデータの持ち方によるものだと思いますが、利用方法の詳細や実際の使い分けまではまだ理解していません。


parse() と fields() のまとめ



まず、メソッド parse() は、読み込んだ行を適切なフィールドに分割します。

僕が初めに奇妙に感じたのは、分割されたフィールドを受け取る変数が不要なことです。


$csv->parse($_);


この記述だけで、$_ に格納された CSV 形式の文字列行はフィールドに分割されますが、分割されたフィールドを誰が持っているのか分からなかった訳です。

この疑問は、Perl デバッガを利用して、オブジェクトの中身を確認して解消しました。parse() が分割したデータは、オブジェクトが用意したデータ領域に格納されていたということです。

メソッド fields() は、このオブジェクトが保持しているフィールドのデータリストを任意取り出すためのメソッドです。

次の様に記述することで、fields() はフィールドのリストを返すことが出来ます。


@fields = $csv->fields();


これで、配列 @fields() の各要素には、parse() で分割された各フィールドが格納されます。


0xb9 -> 0xba へ



次回は、実際に作成したコードをベースに、CSV データの処理を確認する予定です。

ところで、「 Comma-Separated Values 」の略で CSV,「 Tab-Separated Values 」の略で TSV とするのは良く分かりますが、「 Character-Separated Values 」で CSV としたのは誰なんでしょうか。

「 space-separated values 」で SSV とか、「 semicolon-separated values 」で SSV とか。

もうね、どうしたら読み分けがつくと思ったのか詳しく聞いてみたいものです。

Comma-Separated Values - Wikipedia

参考情報は以下の書籍を中心に Wikipedia および各 Web サイト。それと詳しい先輩。

参考 :「Randal L. Schwartz, brian d foy, Tom Phoenix 共著 近藤 嘉雪 訳「初めての Perl 第 6 版」(オライリー・ジャパン発行 ISBN978-4-87311-567-2)」


次回 (0ba) へ続く。

目次 - Perl Index











同じカテゴリー(Perl)の記事
 Perl mp2 翻訳 Web コンテンツ圧縮の FAQ (d228) (2023-10-11 23:49)
 Perl mp2 翻訳 既知のブラウザのバグの回避策をいくつか (d227) (2023-05-26 15:41)
 Perl mp2 翻訳 Perl と Apache でのキュートなトリック (d226) (2023-05-19 17:05)
 Perl mp2 翻訳 テンプレートシステムの選択 (d225) (2022-08-15 22:23)
 Perl mp2 翻訳 大規模 E コマースサイトの構築 (d224) (2022-06-15 20:43)
 Perl mp2 翻訳 チュートリアル (d223) (2022-06-15 20:42)
上の画像に書かれている文字を入力して下さい
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。

Llama
リャマ
TI-DA
てぃーだブログ
プロフィール
セラ (perlackline)
セラ (perlackline)
QRコード
QRCODE
オーナーへメッセージ

PAGE TOP ▲