none
文字エンコードが可能かどうか事前に調べられない? RRS feed

  • 質問

  • お世話になります。

    Encoding クラスを使って、あるエンコードのバイト列から、別のエンコードのバイト列に変換することができます。
    これによって、例えば Shift-JIS で書かれたテキストファイルを EUC-JP で保存しなおしたりできます。
    この時、例えば Shift-JIS で書かれたテキストファイルを US-ASCII で保存しようとしたら、文字化けするという旨、事前に知る方法はないでしょうか?

    .NET Framework 2.0 からフォールバッククラスが提供され、変換中にエンコード不可能なデータに遭遇した時の挙動が決められますが、実際に変換してみる前に判定したいのです。
    Encoding クラスごとに扱えるキャラクタセットはあらかじめ決まっているはずなので、2つの Encoding オブジェクトが扱えるキャラクタセットに互換性があるかどうか調べる CanConvertTo みたいなメソッドがないかと思っているのですが、何か方法がありますでしょうか?

    宜しくお願いいたします。

    [追記]

    Win32 API でエンコードを扱うための IMultiLanguage インターフェイスには IsConvertible メソッドがありますね。
    これと同等のことを .NET でやりたいわけです。

    2006年11月17日 18:24

回答

  • すべてのコードポイントを対象として、2つの Encoding の和集合や補集合のサイズが知りたいんですよね。これは「~」のような記号や、CJK のようなキャラクタセットが部分集合を持つ文字を考慮すると、簡単に範囲とか文字カテゴリで情報をもてないだろうと思います。
     
    このため、上記を求めるには、2つの Encoding の実装、Encoding1, Encoding2 に対して、Encoding1 がサポートするコードポイントのすべてを含んだ長大な文字列を Encoding2 に食わせてみるしかないと思います。
    # 現状でやろうとすると、Enconding1 のサポートする文字列を作成するために、U+00000000 ~U+FFFFFFFF の約42億文字程度を1回変換してから、それを Encoding2 で再変換することになりそうです
     
    「なんとなく、このあたりの文字はサポートしている(日本語が使えますよ、程度)」 というようないい加減なレベルで調べるなら簡単なんでしょうけど、そのような不正確な情報を得るためのインターフェスや、そのような不正確なデータそのものが .NET のクラスライブラリには用意されていないでしょう。
     
    ちなみに、サロゲートをサポートしない前提で BMP 領域を視点コードポイントと終点コードポイントのペアのリストで管理して、上記の変換テストを実装したことならあったりします。
     
    2006年11月28日 20:39

すべての返信

  • // 回答ではありません。

    IMultiLanguage::IsConvertible は、あくまであるコードページから他のコードページへの変換を実行できるかどうかを返すのであって、変換しきれないかどうかは考慮する必要はありません(と言うか考慮したらこのインターフェイスメソッドの定義から外れてしまうでしょう)。ご希望の機能ではないと思います。

    それに、(所謂半角の)アルファベットのみで構成された文字列なら、Unicode(UTF-16)で書かれたテキストファイルを Shift_JIS で保存しても文字化けしませんが、それはどうなんでしょうか?

    2006年11月18日 1:25
  •  シャノン さんからの引用

    実際に変換してみる前に判定したいのです。

    無理です。

    「変換可能かどうか」を調べるには、少なくとも変換もとの文字列全部をスキャンする必要があるので、仮にそういうメソッドがあったとしても、実効コストは「実際に返還してみる」のと大差ないことになります。

     

    2006年11月18日 2:44
    モデレータ
  •  Hongliang さんからの引用

    // 回答ではありません。

    IMultiLanguage::IsConvertible は、あくまであるコードページから他のコードページへの変換を実行できるかどうかを返すのであって、変換しきれないかどうかは考慮する必要はありません(と言うか考慮したらこのインターフェイスメソッドの定義から外れてしまうでしょう)。ご希望の機能ではないと思います。

    試してみたところ、コードページ65000(UTF-8)から1252(西ヨーロッパ言語)への変換が可能であるということでした。
    このメソッドが判定するのは、システムが変換する能力を持っているかどうかであって、文字化けしないかどうかではないのですね。

     Hongliang さんからの引用

    それに、(所謂半角の)アルファベットのみで構成された文字列なら、Unicode(UTF-16)で書かれたテキストファイルを Shift_JIS で保存しても文字化けしませんが、それはどうなんでしょうか?

    そうですね。

    より正確には、UTF-16 文字列はアルファベット以外も含んでいる可能性があり、そのため、Shift_JIS に変換したら文字化けする可能性がある。
    その可能性の有無がわかればよい、ということになります。

    2006年11月18日 5:18
  •  渋木宏明 さんからの引用
     シャノン さんからの引用

    実際に変換してみる前に判定したいのです。

    無理です。

    「変換可能かどうか」を調べるには、少なくとも変換もとの文字列全部をスキャンする必要があるので、仮にそういうメソッドがあったとしても、実効コストは「実際に返還してみる」のと大差ないことになります。

     

    ありがとうございます。

    Hongliangさんへの返信でも書きましたが、正しくは「変換できない可能性があるかどうか」が調べられれば目的は達せられます。

    そのためには、「変換元のエンコードがサポートしているキャラクタセットを、変換先のエンコードもサポートしているかどうか」がわかればよいと思うのですが、これを判定する方法はないでしょうか。

    あるいは、他の方法であっても、上記の要件が満たせれば構いません。

    2006年11月18日 5:22
  • というわけで、一点訂正します。

    例えば、Shift_JIS 文字列は UTF-8 文字列に確実に変換可能であるが、逆は必ずしも可能ではないように、「確実に可能」か「そうとは限らない」かを判定したいのです。

    贅沢を言えば「可能」「(不)可能かもしれない」「不可能」の3択で判定できると嬉しいのですが、ダメなら「可能」「可能とは限らない」の2択でも構いません。

    2006年11月18日 7:18
  • すべてのコードポイントを対象として、2つの Encoding の和集合や補集合のサイズが知りたいんですよね。これは「~」のような記号や、CJK のようなキャラクタセットが部分集合を持つ文字を考慮すると、簡単に範囲とか文字カテゴリで情報をもてないだろうと思います。
     
    このため、上記を求めるには、2つの Encoding の実装、Encoding1, Encoding2 に対して、Encoding1 がサポートするコードポイントのすべてを含んだ長大な文字列を Encoding2 に食わせてみるしかないと思います。
    # 現状でやろうとすると、Enconding1 のサポートする文字列を作成するために、U+00000000 ~U+FFFFFFFF の約42億文字程度を1回変換してから、それを Encoding2 で再変換することになりそうです
     
    「なんとなく、このあたりの文字はサポートしている(日本語が使えますよ、程度)」 というようないい加減なレベルで調べるなら簡単なんでしょうけど、そのような不正確な情報を得るためのインターフェスや、そのような不正確なデータそのものが .NET のクラスライブラリには用意されていないでしょう。
     
    ちなみに、サロゲートをサポートしない前提で BMP 領域を視点コードポイントと終点コードポイントのペアのリストで管理して、上記の変換テストを実装したことならあったりします。
     
    2006年11月28日 20:39
  • すべてのコードポイントを対象として、2つの Encoding の和集合や補集合のサイズが知りたいんですよね。

    サイズというか…

    Encoding1(がサポートする文字集合)⊆Encoding2(がサポートする文字集合) なのか

    Encoding1∩Encoding2≠φ なのか

    Encoding1∩Encoding2=φ なのか

    どれなのかが判定できればいいんですけどね…。

    やはり「いざ変換するまでわからない」ということですね…。

    2006年12月1日 14:33