[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 メーリングリストの案内