Help us understand the problem. What is going on with this article?

MacJapanese, CP932, Shift_JIS の違いと Ruby での取り扱い

More than 3 years have passed since last update.

前置き

 文字コードに混乱させられて酷い目にあったので、犠牲者を減らすため整理しました。3つの文字コードについての話題です。Shift_JIS (http://ja.wikipedia.org/wiki/Shift_JIS), MacJapanese (http://ja.wikipedia.org/wiki/MacJapanese), CP932 (http://ja.wikipedia.org/wiki/Microsoftコードページ932) の違いについてまとめます。また、それらを Ruby で扱う際の注意点について説明します。

MacJapanese, CP932, Shift_JIS の違い

 上にあげた3つの文字コードは文字-バイト列の変換方式であり、文字-バイト列の対応表でもあります。いずれも同じ変換方式を使いますが、持っている対応表が異なります。この中では Shift_JIS の対応表が最も小さなものになります。MacJapanese, CP932 は Shift_JIS の対応表をそれぞれ独立に拡張したものです。たとえば文字 は Shift_JIS, MacJapanese, CP932 のどれでも 0x82A0 に対応します。しかし文字 (ローマ数字の1) は Shift_JIS には存在せず、MacJapanese では 0x859F であり、 CP932 では 0x8754 に対応します。表にすると下のようになります。

Shift_JIS MacJapanese CP932
0x82A0 0x82A0 0x82A0
ローマ数字の1 無し 0x859F 0x8754

ローマ数字のⅠ,Ⅱ,Ⅲ... の他に囲み文字 ①,②,③... もそれぞれ異なるバイト列になります。

MacJapanese が使われているアプリケーション

 ほとんど見かけないのですが、絶滅しているわけではありません。Microsoft Excel のファイル *.xls または *.xlsx を Mac 版 Office で CSV 出力すると MacJapanese になります。Windows 版 Office で同じ操作をすると CP932 の CSV ファイルが出力されます。非常にややこしいですね。また、Mac 標準のメーラーも MacJapanese を使っているようです。

Ruby での取り扱い

 Ruby で Shift_JIS, CP932, MacJapanese のファイルを読み込むことを考えます。Shift_JIS や CP932 であれば、File.read("hoge.txt", encoding: 'CP932') のように引数で文字コードを指定すれば良いので問題ありません。

 ところが MacJapanese の場合は文字コードを指定してもエラーになります。なぜならば、Ruby は MacJapanese の変換表を持たないためです。たとえば "あ".encode("MacJapanese") を実行すると Encoding::ConverterNotFoundError が発生します。(そのスクリプト自体を MacJapanese で書けばエラーは起こらないかもしれません)

 最も良い方法は、MacJapanese で書かれたファイルを仕様から外すことです。与えられたファイルが Shift_JIS か MacJapanese か CP932 かを判断するのは困難ですし、ファイルを作成したユーザさえそのことを知らないのが普通です。MacJapanese が作られる状況は限定的ですので「Mac 版エクセルを使用しないでください」で事足りる場合も多いと思います。

 次善策として、全てのファイルを Shift_JIS として扱う方法があります。この方法は、ほとんどの文字に対して、期待した結果が得られます。もちろん、文書中に①などの文字が使われている場合、簡単にはいきません。たとえば "①".encode("Shift_JIS")Encoding::UndefinedConversionError を発生させます。この例外を rescue して、無効な文字に置き換えるか、ユーザに訂正を促すなどの対処が必要です。ただこの場合は CP932 も引っかかってしまうので、傷口が広がってしまうかもしれません。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした