[PHP-users 17539]Re: SJIS-EUC変換時の文字化け

Osamu Shigematsu m5issige @ mr.hitachi-medical.co.jp
2003年 8月 27日 (水) 15:23:54 JST


重松です。こんにちは。

> \がくると、fgetcsvは、エスケープとして処理してしまうのです。
> なので、SJISの場合、2バイト目が、¥(5c)になる様な文字がくると
> そこで、ずれるので、文字化けになるのです。

まあ、そんな落ちだろうとは推測してました。

> しかし、私は、csvには、その仕様の歴史的経緯から、¥でエスケープするという
> 概念は、ないはずだという、立場です。
> 
> もともと、csvは
> MS-BASICのINPUT文に、そのまま突っ込めるデータなんですよ。
> 1980年初頭に、VISICALCが使用したのが最初だったと思います。
> ¥でエスケープされたら、\1000って書きたいとき、¥¥1000てかかないと
> ならなくなりますよね。
> 
> ようするにcsvは、BASICの文法で困らない、データ形式なわけで
> 同じく、BASICで困らない様に、日本語をつかう様に定義されたのが
> SJIS(MS-漢字:CP/M漢字)です。
> この場合、BASICに¥でエスケープするなんて概念がなかったので
> 2バイト目に¥がくるのです。逆に、"などが絶対にこない様になっています。

だとすると、そもそも、\ を含む場合には、\\ にしたデータを作らないといけ
ないことになりますね。

手元の Windows XP におまけで付いてきてた Excel に \\ "" '' ,, (各二文字
ずつ) を各セルに入力して CSV で保存したところ、以下のようになりました。

\\,"""""",',",,"

このことから、明らかに \ をエスケープ文字として扱うのは誤りである、と思
います。(だって、M$ 様の Excel がそういう動きなのだから)

それとは逆に、" は "" と二つになって、かつ、, などを含む場合には "" でく
くる、ということのようですね。
# このあたり、どこかに仕様書が落ちていそうな気もしますが。>M$

いずれにしても、コード変換が絡むと、fgets ってあまり便利でない気がします。

逆に、mb_split でぶった切れる美しい正規表現などのほうが幸せかも。

$rows = array();
$fp = fopen('csv.txt', 'r');
while ($line = fgets($fp)) {
	$line = mb_convert_encoding($line, "EUC-JP", "SJIS");
	$cols = mb_split('CSVの項目に分ける正規表現', $line);
	$rows[] = $cols;
}

見たいにするとか、場合によっては、file() で一気読みしてから、切るとか。

-- 
Osamu Shigematsu <m5issige @ mr.hitachi-medical.co.jp>



PHP-users メーリングリストの案内