文字コードの勉強(正規表現がらみ)。

 なんで突然,文字コードのお勉強に取り組んでいるかというと,久しぶりに,Joyful Note を見に行ったら,Ver.4.5 になっていて,カスタマイズしようと思ったら,正規表現で引っかかっちゃったのだ。何で,Joyful Note のカスタマイズに取り組もうとしているかというと,去年かかわったこれのせい。

 引っかかったのは, joyful.cgi の中の,
     # キーワード検索準備(Shift_JIS定義)
     my $ascii = ‘[\x00-\x7F]’;
     my $hanka = ‘[\xA1-\xDF]’;
     my $kanji = ‘[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]’;
というところ。これは,もとの掲示板が Shift_JIS エンコードだから,(Shift_JIS定義)をやっているのだろう。ということは, EUC-JP にするなら,当然,(EUC-JP定義)を, UTF-8 にするなら,(UTF-8定義)をしなければいけないのではないかと思ったわけだ。前のバージョン(この間カスタマイズしたのは,3.71)には,この部分はなかった。実際には,同じ作業をやっている部分があったのかもしれないが,こういう形では見えなかったので,気づかなかった。

 で,まずは改めて文字コードのお勉強から。参考にさせていただいたサイトはここ。参考にさせていただいたところは,間違いないようだが,文字コードについては,間違ったことを書いているところもあったから,要注意。まぁ,ネットていうのは,いつもそうだけどね。不安なときの確認は,やはり,本家。JISについては, 日本工業標準調査会 , UNICODE については, The Unicode Consortium を参照すること。
 それから, Unicode そのものや Unicode と UTF-8 や UTF-16 との関係についての話は,ここの説明が一番よくわかった。大変に読みやすい。ありがたかった。

 では,順番に調べて行ってみる。

  1. $ascii = ‘[\x00-\x7F]’ について。
    これは,EUC-JP,UTF-8でも同じだから,このままでいいだろう。

    • 注:厳密にいうと,UTF-8の場合,円マーク &#x00A5 (Shift_JIS,EUC-JPと同じ16進コードの場合は &#x005C になる) とオーバーライン &#x203E (Shift_JIS,EUC-JPと同じ16進コードの場合は &#x007E になる) は,( )内に書いたように異なっている。オーバーラインのほうはあまり意識に上ってこないかもしれないが, &#x00A5 を打ったつもりなのに,表示が &#x005C になってしまったという経験は,よくあると思う。日本語用フォントにおいて,この部分は,いまだに特例扱いのようだ。何しろ,円マークは日本の一般社会の頻出記号だから,さかのぼって直すとなると大変なんだろうと,推察した。本当の理由は知らない。
  2. $hanka = ‘[\xA1-\xDF]’ について。
    これは, JIS0201.TXT の第1列をを見ると,半角カナの話であることが分かる。半角カナは,EUC-JPでは, 8EA1~8EDF だから,$hanka = ‘\x8E[\xA1-\xDF]’でいいのか。それとも,EUC-JP の場合,1バイト目に 8E が出て来るのは,半角カナだけだから, \x8E 部分のチェックだけでいいのだろうか。この辺は,実装の問題なのか?

    JIS0201.TXT 見ると,UNICODEの場合,半角カナに対応するのは,FF61~FF9Fとなっている。これを The Unicode Consortium の文書 Conformance の Table 3-6. UTF-8 Bit Distribution と Table 3-7. Well-Formed UTF-8 Byte Sequences に則って変換してみる。
    UNICODEからUTF-8へ
      
     まずは,FF61 (16進) —> 11111111 01100001 (2進) とする。
     Table 3-6.に照らし合わせると,対応は以下のようになる。

    z z z z y y y y y y x x x x x x
    1 1 1 1 1 1 1 1 0 1 1 0 0 0 0 1

     さらに,Table 3-6.のルールを適用すると,結局,1バイト目から3バイト目は,以下の3つの2進数になる。

    1バイト目 2バイト目 3バイト目
    ルール 1 1 1 0 z z z z 1 0 y y y y y y 1 0 x x x x x x
    対応する2進数 1 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1 1 0 1 0 0 0 0 1

    したがって,11101111 10111101 10100001 (2進) —> EFBDA1 (16進) となることがわかる。同様に,FF9F (16進) —> EFBE9F (16進) になる。

    細かく調べてみると, UTF-8 で Shift_JIS の A1~DF に対応する部分は, EFBDA1~EFBDBF までと, EFBE80~EFBE9F に分かれていることがわかる。ということになると, UTF-8 の場合は,
    $hanka = ‘\xEF\xBD[\xA1-\xBF]|\xEF\xBE[\x80-\x9F]’
    ということになりそうだ。

  3. $kanji = ‘[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]’ について。
    これは, JIS0208.TXT の第1列だと,実体のあるところだけをズラッと並べてあるから見づらいんだが,範囲は Shift_JIS だと,上位1バイト 0x81~0x9f , 0xe0~0xef ,下位1バイト 0x40~0x7e , 0x80~0xfc に収まっている。 JISX0208 の範囲だから,JIS第1第2水準漢字だということだ。
    まあ,この範囲だと, EUC-JP は,上位1バイトも下位1バイトも 0xa1~0xfe に収まっているから,多分,$kanji = ‘[\xA1-\xFE][\xA1-\xFE]’ でいいんだろう。

    問題は UTF-8 で, Shift_JIS と EUC-JP はコードにしたときの並び順が同じだからいいが, UTF-8 は UNICODE 由来だから順序が違う。といって, Shift_JIS と EUC-JP の順序を無視して, UNICODE だけで行くと,日本語では一般的でない漢字も遠慮なく入ってくる。その辺が,日本国内を視点に考えられた Shift_JIS ・ EUC-JP と, UNICODE の違いだ。
    こういう場合は,1度 UTF-8 になっているものを EUC-JP とかに戻して考えるのが一般的なのだろうか。

    どういう方法が,一般的なのかは,別にして, JISX0208 の範囲の UNICODE から, UTF-8 を考えて変換表を作ってみた。上記の参考ページにあるようなものを自前で作ってみたわけだ。これをやるには,いろんな方法があるのだろうが,使い慣れているEXCELでやってみた。で,出来上がったのが,これ。並び順は,作成した UTF-8 順。UTF-8 と UNICODE の部分の色分けは,Table 3-7.の Well-Formed の確認のためにつけたもの。 Shift_JIS と字の部分の色分けは,青が第一水準,黄が第二水準(厳密にいうと,第一,第二は漢字に対して使うものらしいが……)。

    漢字の部分で,青と黄が入り混じっている。おまけに, UTF-8 は連続数になっていない。 UNICODE の漢字は基本的に画数で並んでいるから,常用漢字が基本に来る JIS と対比すると,こうなるのはまあ当然。うーん,やはり,EUC-JP に戻してフィルタかけるのが現実的なのかなぁ。

と,ここまでやってきて,ようやく,Joyful Note のカスタマイズに入れそうな気がしてきたが,まだ簡単には,行きそうにない(爆)。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください