UTF-8で円記号を入出力させる

「UTF-8で円記号を入出力させる」って、何の事を言っているんだ?
あたりまえに入力できるんじゃないの?

と、思っている方、あまーい!

EUC-JPやShift-JISからUTF-8に移行した場合、IEでは円記号の表示がバックスラッシュになってしまいます。
また、テキストボックスなどで入力する際も同様です。
さらに、Linuxではバックスラッシュになってしまいます。

対策には結構工夫が必要でした。

円記号の表示

始めにお断りしておきますが、単純に(PHPのprintなどで)文字列を表示している場合はお手上げです。
こういった事をしている方は、まちがいなく初心者レベルです。以下の方法では、間違いなく一から作り直しです。

さて、円記号がバックスラッシュで表示される原因ですが、日本人が通常円記号として使っているコードは、日本国内のみ円記号として使う約束なのです。
インターネットは国の枠を超えていますので、こういった文字がどう表示されても文句は言えません。使うべきでない文字です。

HTMLでは円記号は¥と表記すれば正しく表示されます。

現在のWeb技術者の常識として、HTMLになにかしらデータを表示する際には、ハッキングされないよう、ユーザ関数で < を &lt; などと変換して表示しているはずです。

このユーザ関数に、円記号を &yen; に変換する処理を追加して対策できます。

ちなみに、半角スペースは &nbsp; に変換して表示します。これをしておかないと、空白の連続は1文字の空白にまとめられてしまいます。

円記号を入力

円記号を入力するには、バックスラッシュキーを入力された時、この文字をUTF-8の円記号に置き換えてしまえばいいわけです。
これにはJavaScriptを使う以外ありませんでした。

function text_key_press(obj, e){
if (document.all) {
if (event.keyCode == 0x5c) {
event.keyCode = 0x00a5;
}
} else {
if (e.which == 0x5c) {
var sPos = obj.selectionStart;
var ePos = obj.selectionEnd;
var str = obj.value.substring(sPos, ePos);
obj.value = obj.value.substring(0, sPos) + unescape('%u00a5') + obj.value.substr(ePos);
obj.setSelectionRange(sPos + 1, sPos + 1);
return false;
}
}
return true;
}

と、JavaScriptの関数を定義しておきます。

※ JavaScriptでのkeyCodeは、UTF-16のようですので、注意が必要です。

<input type="text" name="memo" onkeypress="return text_key_press(this, event);" />

等として、入力されたときに呼び出します。

また、これによって入力した円記号のPOSTの値は、0xc2a5となります。
「円記号を表示」と整合性をあわせるため、これを円記号に変換します。

ちなみに &nbsp; のPOSTの値は、0xc2a0となりますので、これを半角スペースに変換します。

全体的な考え方

上記では、以下のような基本的な考え方に従っている。

・現行の円記号はそのまま。データ移行のコストがかからない。
・入出力の時点で文字コードは内部文字コードに統一する。

こういった基本方針がはっきりしていないと、いつまでもバグや例外処理のメンテナンスを行うはめになる。

1件のコメント

  1. ピンバック: リンク集 [Junsei Chiba]

コメントする

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

*

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