ラベル Unicode の投稿を表示しています。 すべての投稿を表示
ラベル Unicode の投稿を表示しています。 すべての投稿を表示

2017年7月5日

PerlのEncode::JIS2KとPython

以前に自分が書いた記事が矢野さんに取り上げられて大変嬉しかったので、引き続きいろいろな処理系でのJIS X 0213の実装状況を調べていたのですが、Pythonと同様な変換を持った実装を見付けました。

Unicode の嫌なところを触ってしまった Python
http://yanok.net/2017/06/unicode-python.html

それがPerlのEncode::JIS2Kモジュールなのですが、

Encode::JIS2K - search.cpan.org
http://search.cpan.org/~dankogai/Encode-JIS2K/JIS2K.pm

こちらもPythonと同様にこのような変換を持っていました。

JIS X 0213Unicode
1面2区54点U+2985LEFT WHITE PARENTHESIS
1面2区55点U+2986RIGHT WHITE PARENTHESIS

もしかすると、PerlのEncode::JIS2Kモジュールを実装された方とPythonのcodecsモジュールを実装された方が、偶々どこかの同じ資料を参照していたのかもしれません。

ちなみに、その他の実装では大抵このような変換になっています。

JIS X 0213Unicode
1面2区54点U+FF5FFULLWIDTH LEFT WHITE PARENTHESIS
1面2区55点U+FF60FULLWIDTH RIGHT WHITE PARENTHESIS

Encode::JIS2Kは、
  • JIS X 0213の2004年改正に未対応
  • Unicodeへの変換結果が結合文字列となる文字に未対応
といった特徴があるので、特段の理由が無ければEncode::JISX0213およびEncode::ShiftJIS2003を使用したほうが良いかもしれません。

Encode::JISX0213 - search.cpan.org
http://search.cpan.org/~nezumi/Encode-JISX0213-0.04/lib/Encode/JISX0213.pm
Encode::ShiftJIS2004 - search.cpan.org
http://search.cpan.org/~nezumi/Encode-JISX0213-0.04/lib/Encode/ShiftJIS2004.pm

2016年12月4日

主な実装における EUC-JIS-2004, Shift_JIS-2004 から Unicode への変換結果の違い

まとめました。


nkfとiconvの差異
https://nathancorvussolis.blogspot.jp/2015/05/difference-between-nkf-and-iconv.html

Pythonとiconvの差異
https://nathancorvussolis.blogspot.jp/2016/11/difference-between-python-and-iconv.html

JavaのShift_JIS-2004については下記のブログを引用させていただきました。
iconv、Java、PythonのJISX0213 - yuan-jiu blog
http://yuan-jiu.asablo.jp/blog/2013/05/11/6807043


バージョン

libiconv 1.14
nkf 2.1.4
Python 3.4.5
Java 1.7.0_21


EUC-JIS-2004


EUC-JIS-2004iconvnkfPython
0xA1B1 U+FFE3 U+203E U+FFE3
0xA1EF U+FFE5 ¥U+00A5U+FFE5
0xA1BD U+2014 U+2014 U+2015
0xA2D6 U+FF5F U+FF5FU+2985
0xA2D7 U+FF60 U+FF60 U+2986

http://x0213.org/codetable/euc-jis-2004-std.txt より抜粋
0xA1B1  U+203E  # OVERLINE  Windows: U+FFE3
0xA1BD  U+2014  # EM DASH  Windows: U+2015
0xA1EF  U+00A5  # YEN SIGN  Windows: U+FFE5
0xA2D6  U+FF5F  # FULLWIDTH LEFT WHITE PARENTHESIS  [2000]  [Unicode3.2]
0xA2D7  U+FF60  # FULLWIDTH RIGHT WHITE PARENTHESIS  [2000]  [Unicode3.2]

EUC-JIS-2004 については FULLWIDTH かどうかの違いくらいしかないので、それほど問題はなさそうです。
Python の 0xA2D6 → U+2985 と 0xA2D7 → U+2986 はちょっとどうなの?と思ってしまいますが。


Shift_JIS-2004


Shift_JIS-2004iconvnkfPythonJava
0x5C ¥U+00A5 \U+005C ¥U+00A5 \U+005C
0x7E U+203E ~U+007E U+203E ~U+007E
0x8150 U+FFE3 U+203E U+FFE3 U+FFE3
0x815C U+2014 U+2014 U+2015 U+2014
0x815F U+FF3C U+FF3C \U+005C U+FF3C
0x818F U+FFE5 ¥U+00A5 U+FFE5 U+FFE5
0x81B0 U+FF5E U+FF5E ~U+007E U+FF5E
0x81D4 U+FF5F U+FF5F U+2985 U+FF5F
0x81D5 U+FF60 U+FF60 U+2986 U+FF60

http://x0213.org/codetable/sjis-0213-2004-std.txt より抜粋
0x5C    U+00A5  # YEN SIGN
0x7E    U+203E  # OVERLINE
0x8150  U+FFE3  # FULLWIDTH MACRON
0x815C  U+2014  # EM DASH  Windows: U+2015
0x815F  U+005C  # REVERSE SOLIDUS  Fullwidth: U+FF3C
0x818F  U+FFE5  # FULLWIDTH YEN SIGN
0x81B0  U+007E  # TILDE  [2000]  Fullwidth: U+FF5E
0x81D4  U+FF5F  # FULLWIDTH LEFT WHITE PARENTHESIS  [2000]  [Unicode3.2]
0x81D5  U+FF60  # FULLWIDTH RIGHT WHITE PARENTHESIS  [2000]  [Unicode3.2]

こうして見てみると、Python の 0x815F → U+005C がはまりポイントになりそうですね。

2016年11月30日

Pythonとiconvの差異

PythonとiconvとでJIS系文字コードとUnicodeとの変換にどれくらい違いがあるのか調べてみました。

EUC-JIS-2004とShift_JIS-2004のファイルをそれぞれUTF-8に変換して、その結果を比較します。

Python
https://www.python.org/
 
libiconv
http://www.gnu.org/software/libiconv/

変換元となるファイルについては、プロジェクトX0213の「JIS X 0213とUnicodeの対応表」から、文字付き版のファイルを使用しました。

JIS X 0213とUnicodeの対応表
http://x0213.org/codetable/

EUC-JIS-2004とUnicodeの対応表 文字付き版
http://x0213.org/codetable/euc-jis-2004-with-char.txt
Shift_JIS-2004とUnicodeの対応表  文字付き版
http://x0213.org/codetable/sjis-0213-2004-with-char.txt

今回使用した環境、バージョンは以下の通りです。

  • cygwin 2.6.0 (0.304/5/3)
  • Python 3.4.5
  • libiconv 1.14

追記: Pythonでの変換に使用した pconv.py は以下のようなコードです。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#

import codecs
import sys

if __name__ == "__main__":
    if (len(sys.argv) != 5):
        print('usage: python pconv.py <enc_from> <inputfile> <enc_to> <outputfile>')
        sys.exit(1)

    for arg in sys.argv:
        print(arg)

    output = codecs.open(sys.argv[4], 'w', sys.argv[3])

    for line in codecs.open(sys.argv[2], 'r', sys.argv[1]):
        try:
            output.write(line)
        except UnicodeEncodeError:
            print('UnicodeEncodeError')
            break

    output.close()

EUC-JIS-2004

$ python3 pconv.py euc_jis_2004 euc-jis-2004-with-char.txt utf_8 euc-jis-2004-python.txt
$ iconv -f EUC-JIS-2004 -t UTF-8 euc-jis-2004-with-char.txt > euc-jis-2004-iconv.txt
$ diff euc-jis-2004-python.txt euc-jis-2004-iconv.txt > diff-euc-jis-2004.txt
追記: diff-euc-jis-2004.txt
216c216
< ―    0xA1BD    U+2014    # EM DASH    Windows: U+2015
---
> —    0xA1BD    U+2014    # EM DASH    Windows: U+2015
335,336c335,336
< ⦅    0xA2D6    U+FF5F    # FULLWIDTH LEFT WHITE PARENTHESIS    [2000]    [Unicode3.2]
< ⦆    0xA2D7    U+FF60    # FULLWIDTH RIGHT WHITE PARENTHESIS    [2000]    [Unicode3.2]
---
> ⦅    0xA2D6    U+FF5F    # FULLWIDTH LEFT WHITE PARENTHESIS    [2000]    [Unicode3.2]
> ⦆    0xA2D7    U+FF60    # FULLWIDTH RIGHT WHITE PARENTHESIS    [2000]    [Unicode3.2]

EUC-JIS-2004の変換では、3つの文字で異なる変換結果が得られました。

  • 0xA1BD EM DASH
    • Python U+2015
    • iconv U+2014
  • 0xA2D6 FULLWIDTH LEFT WHITE PARENTHESIS
    • Python U+2985
    • iconv U+FF5F
  • 0xA2D7 FULLWIDTH RIGHT WHITE PARENTHESIS
    • Python U+2986
    • iconv U+FF60

Shift_JIS-2004

$ python3 pconv.py shift_jis_2004 sjis-0213-2004-with-char.txt utf_8 sjis-0213-2004-python.txt
$ iconv -f Shift_JIS-2004 -t UTF-8  sjis-0213-2004-with-char.txt > sjis-0213-2004-iconv.txt
$ diff sjis-0213-2004-python.txt sjis-0213-2004-iconv.txt > diff-sjis-0213-2004.txt
追記: diff-sjis-0213-2004.txt
310c310
< ―    0x815C    U+2014    # EM DASH    Windows: U+2015
---
> —    0x815C    U+2014    # EM DASH    Windows: U+2015
313c313
< \    0x815F    U+005C    # REVERSE SOLIDUS    Fullwidth: U+FF3C
---
> \    0x815F    U+005C    # REVERSE SOLIDUS    Fullwidth: U+FF3C
393c393
< ~    0x81B0    U+007E    # TILDE    [2000]    Fullwidth: U+FF5E
---
> ~    0x81B0    U+007E    # TILDE    [2000]    Fullwidth: U+FF5E
429,430c429,430
< ⦅    0x81D4    U+FF5F    # FULLWIDTH LEFT WHITE PARENTHESIS    [2000]    [Unicode3.2]
< ⦆    0x81D5    U+FF60    # FULLWIDTH RIGHT WHITE PARENTHESIS    [2000]    [Unicode3.2]
---
> ⦅    0x81D4    U+FF5F    # FULLWIDTH LEFT WHITE PARENTHESIS    [2000]    [Unicode3.2]
> ⦆    0x81D5    U+FF60    # FULLWIDTH RIGHT WHITE PARENTHESIS    [2000]    [Unicode3.2]

Shift_JIS-2004の変換では、5つの文字で異なる変換結果が得られました。

  • 0x815C EM DASH
    • Python U+2015
    • iconv U+2014
  • 0x815F REVERSE SOLIDUS
    • Python U+005C
    • iconv U+FF3C
  • 0x81B0 TILDE
    • Python U+007E
    • iconv U+FF5E
  • 0x81D4 FULLWIDTH LEFT WHITE PARENTHESIS
    • Python U+2985
    • iconv U+FF5F
  • 0x81D5 FULLWIDTH RIGHT WHITE PARENTHESIS
    • Python U+2986
    • iconv U+FF60

まとめ


FULLWIDTH LEFT WHITE PARENTHESIS と FULLWIDTH RIGHT WHITE PARENTHESIS が FULLWIDTH でなくなってしまうのが、Pythonのいまいちな点でしょうか。

今回の使用・作成したファイルをGitHubに上げていますので、興味のある方はご覧ください。
https://github.com/nathancorvussolis/difference-between-python-and-iconv

さらに追記:
すでにShift_JIS-2004の変換をまとめている方がおられたのでリンクしておきます。
iconv、Java、PythonのJISX0213 - yuan-jiu blog
http://yuan-jiu.asablo.jp/blog/2013/05/11/6807043

2015年5月10日

nkfとiconvの差異

JIS系文字コードとUnicodeとの変換によく使われるnkfとiconvの変換にどれくらい違いがあるのか調べてみました。

EUC-JIS-2004とShift_JIS-2004のファイルをそれぞれUTF-8に変換して、その結果を比較します。

nkf Network Kanji Filter
http://sourceforge.jp/projects/nkf/

libiconv
http://www.gnu.org/software/libiconv/

変換元となるファイルについては、プロジェクトX0213の「JIS X 0213とUnicodeの対応表」から、文字付き版のファイルを使用しました。

JIS X 0213とUnicodeの対応表
http://x0213.org/codetable/

EUC-JIS-2004とUnicodeの対応表 文字付き版
http://x0213.org/codetable/euc-jis-2004-with-char.txt

Shift_JIS-2004とUnicodeの対応表  文字付き版
http://x0213.org/codetable/sjis-0213-2004-with-char.txt


今回使用した環境、バージョンは以下の通りです。

  • cygwin 2.0.2 (0.287/5/3)
  • gcc 4.9.2
  • nkf 2.1.3
  • libiconv 1.14

ちなみにJIS X 0213のサポートは、nkfでは2.1.3から、libiconvではおそらく1.8(?)からのようです。


    ビルド

    まず、それぞれをビルドします。

    nkf 2.1.3 をビルド。

    $ tar zxf nkf-2.1.3.tar.gz 
    $ cd nkf-2.1.3
    $ make

    libiconv 1.14 をビルド。EUC-JIS-2004とShift_JIS-2004を使えるようにするため、オプション --enable-extra-encodings を指定します。 

    $ tar zxf libiconv-1.14.tar.gz
    $ cd libiconv-1.14
    $ ./configure --enable-extra-encodings
    $ make

    EUC-JIS-2004

    次に、EUC-JIS-2004の変換をします。

    nkf
    JIS X 0201 片仮名を JIS X 0208 片仮名に変換しないように、オプション -x を指定します。

    $ nkf-2.1.3/nkf -x --ic=EUC-JIS-2004 --oc=UTF-8 euc-jis-2004-with-char.txt > euc-jis-2004-nkf.txt

    iconv
    $ libiconv-1.14/src/iconv_no_i18n -f EUC-JIS-2004 -t UTF-8  euc-jis-2004-with-char.txt > euc-jis-2004-iconv.txt

    それぞれの出力ファイルを比較します。

    $ diff  euc-jis-2004-nkf.txt euc-jis-2004-iconv.txt
    204c204
    < ‾     0xA1B1  U+203E  # OVERLINE      Windows: U+FFE3
    ---
    >  ̄    0xA1B1  U+203E  # OVERLINE      Windows: U+FFE3
    266c266
    < ¥     0xA1EF  U+00A5  # YEN SIGN      Windows: U+FFE5
    ---
    > ¥    0xA1EF  U+00A5  # YEN SIGN      Windows: U+FFE5

    EUC-JIS-2004の変換では、2つの文字で異なる変換結果が得られました。

    • オーバーライン (0xA1B1)
      • nkf   U+203E
      • iconv   U+FFE3
    • 円記号 (0xA1EF)
      • nkf   U+00A5
      • iconv   U+FFE5

    Shift_JIS-2004

    次に、Shift_JIS-2004の変換をします。

    nkf
    JIS X 0201 片仮名を JIS X 0208 片仮名に変換しないように、オプション -x を指定します。
    $ nkf-2.1.3/nkf -x --ic=Shift_JIS-2004 --oc=UTF-8 sjis-0213-2004-with-char.txt > sjis-0213-2004-nkf.txt

    iconv
    $ libiconv-1.14/src/iconv_no_i18n -f Shift_JIS-2004 -t UTF-8  sjis-0213-2004-with-char.txt > sjis-0213-2004-iconv.txt


    それぞれの出力ファイルを比較します。

    $ diff sjis-0213-2004-nkf.txt sjis-0213-2004-iconv.txt
    118c118
    < \     0x5C    U+00A5  # YEN SIGN
    ---
    > ¥     0x5C    U+00A5  # YEN SIGN
    152c152
    < ~     0x7E    U+203E  # OVERLINE
    ---
    > ‾     0x7E    U+203E  # OVERLINE
    298c298
    < ‾     0x8150  U+FFE3  # FULLWIDTH MACRON
    ---
    >  ̄    0x8150  U+FFE3  # FULLWIDTH MACRON
    360c360
    < ¥     0x818F  U+FFE5  # FULLWIDTH YEN SIGN
    ---
    > ¥    0x818F  U+FFE5  # FULLWIDTH YEN SIGN

    Shift_JIS-2004の変換では、4つの文字で異なる変換結果が得られました。

    • 円記号 (0x5C)
      • nkf   U+005C
      • iconv   U+00A5
    • オーバーライン (0x7E)
      • nkf   U+007E
      • iconv   U+203E
    • 全角マクロン (0x8150)
      • nkf   U+203E
      • iconv   U+FFE3
    • 全角円記号 (0x818F)
      • nkf   U+00A5
      • iconv   U+FFE5


    nkfでは、0x5Cと0x7Eは文字の意味に沿って変換するのではなく、ASCII互換として扱うようです。
    で、足りなくなった分を全角マクロンと全角円記号で補っている感じでしょうか。
    この辺りはオプションなどで色々変えられるのかもしれませんが、そこまでは調べませんでした。

    今回の使用・作成したファイルをGitHubに上げていますので、興味のある方はご覧ください。
    https://github.com/nathancorvussolis/difference-between-nkf-and-iconv