チケット #42653

UTF-8 without BOM「日本語①」の自動判定

登録: 2021-07-21 20:37 最終更新: 2022-03-20 21:43

報告者:
担当者:
(未割り当て)
チケットの種類:
状況:
完了
コンポーネント:
(未割り当て)
マイルストーン:
(未割り当て)
優先度:
5 - 中
重要度:
5 - 中
解決法:
直さない
ファイル:
なし

詳細

こんにちは,日本語 TeX の開発関係者です。既に報告があるのかもしれませんが,過去チケットを検索しても見つけられませんでしたので報告します。

現在,Windows 版の pTeX(日本語 TeX)では nkf をライブラリとして組み込んで文字コード推定に使わせて頂いております。その中で,nkf が文字コード推定を誤る例が(ずいぶん前から)指摘されていることに今更気づきました。

確かに nkf 単体で「日本語①」を test.txt として UTF-8 without BOM で保存しても,nkf --guess test.txt で Shift_JIS と返ってきます。ところが

  • 「日」だけ → UTF-8
  • 「日本」まで → UTF-8
  • 「日本語」まで → UTF-8
  • 「日本語①」まで → Shift_JIS
  • 「日本語①あ」まで → UTF-8

となり「日本語①」の時だけ判定を誤るのを不思議に思っています。100%判定が当たるとは思っていませんが,不思議なので理由だけでも分かるとありがたいです。よろしくお願いします。

チケットの履歴 (4 件中 3 件表示)

2021-07-21 20:37 更新者: aminophen
  • 新しいチケット "UTF-8 without BOM「日本語①」の自動判定" が作成されました
2022-03-09 02:37 更新者: None
コメント

「日本語①」の時だけ判定を誤るのを不思議に思っています。 不思議なので理由だけでも分かるとありがたいです

気になったので調べてみました。

「日本語①」 の 文字解析をデバッグ実行した結果を連携します。

nkf の内部では 入力された文字を 1バイトづつ バッファにためておいて

EUC,SJIS,UTF-8 として評価してみて 一番良いスコアの物を採用するというロジックになっています。

「日本語①」 の 場合 SJIS だと 「ソ譌・譛ャ隱樞蔵」になって「漢字,半角カタカナ」と判定されスコアは 131 になります。

EUC だと 変換できない文字があるので 変換エラーフラグが立ち、スコアは非常に悪くなります。

UTF-8 の場合 w_status 関数の中で w2e_conv 関数を呼び unicode_to_jis_common で JIS に変換するために

code_score 関数の中で 「日本語」は漢字として判定されず「①」だけが JIS コード 2D21 に変換され これが 「英数字」 と判定され スコアは 132 となりました。

スコアは小さいほどよく SJIS が 選択される状況となりました。

「①」が来る前までは UTF-8 は 「初期状態」で スコア 128 となっており ① が来るまでは UTF-8 が選択される状況でした。

※ w_status 関数で w2e_conv を呼んだあとで JIS → SJIS 変換 すると UTF-8 でも「漢字」と判定され  UTF-8 の「日本語①」も UTF-8 と判定されるようになるのでは?と思います。

修正してみて、うまく動くようなら バグ修正の プルリクエスト出してみます

kkato233

2022-03-09 23:01 更新者: None
コメント

テストしたら 上記の説明違っていました。 説明消すことできなかったので追記します。

まず追加の調査で分かったのは code_score 関数は JIS または EUC の文字コードで スコア判定する物でした。

スコアで「漢字」だと思っていたのは「第2水準の漢字」でした。

「①」は 環境依存文字という事で 「第2水準の漢字」「半角カナ」よりもスコアが悪いようです。

結論として

UTF-8 の 「日本語①」は

nkf の内部では 評価されたとき

UTF-8 で 「日本語①」   が 「漢字,環境依存文字」と評価され スコアが 132 となり

SJIS では 「ソ譌・譛ャ隱樞蔵」が「第2水準漢字、半角カナ」と評価され スコアが 131 となりました。

①が入ると スコアの悪い UTF-8 の方がスコアが悪くなり SJIS と判定されます。

「日本語①あ」に すると SJIS で表現できない文字が含まれる事になり SJIS のスコアが 387 となり UTF-8 のスコアの方がよくなるため UTF-8 となります。

結論:  「①」は環境依存文字で「半角カナ」や「第2水準漢字」よりも評価が悪い。

 たまたま SJIS で 表示できる文字の場合 SJIS の方が優先されることがある。

 nkf の現在の内部のスコア判定の仕組みでは 回避できない現象のようです。

2022-03-20 21:43 更新者: aminophen
  • 状況オープン から 完了 に更新されました
  • 解決法なし から 直さない に更新されました
コメント

質問者です。反応遅く申し訳ありません。

調べていただきありがとうございます。スコア判定の仕組みによるものとのことで納得しました。

添付ファイルリスト

添付ファイルはありません

編集

ログインしていません。ログインしていない状態では、コメントに記載者の記録が残りません。 » ログインする