こんにちは、 @kz_morita です。
HTML の input フォームで数字のみを受け付けるが,全角の数字は自動的に半角に修正して数値として扱うという仕様を実装した時に,困ったことをまとめてみます.
うまく行かないシンプルな実装
最初は以下のようにシンプルに,全角数値を半角にし,全角ハイフンを -
(マイナス) に変換する実装を行いました.
const replaced = rawValue.replace(/[0-9.]/g, function (s) {
return String.fromCharCode(s.charCodeAt(0) - 65248);
})
.replace(/[ー]/g, '-');
数値の全角から半角の変換は,以下のように,全角の0
と 半角の 0
の差分を確認して,差分を取ることで実現できます.
"0".charCodeAt(0); // => 65296
"0".charCodeAt(0); // => 48
"0".charCodeAt(0) - "0".charCodeAt(0); // => 65248
String.fromCharCode("0".charCodeAt(0) - 65248); // => "0"
問題は,ハイフンとマイナスの変換で上記のようなコードでは,マイナスの値を変換することが出来ませんでした.
ハイフン,ダッシュ,長音多すぎ問題
理由としては,ハイフンやダッシュや長音や全角マイナスなど,同じような見た目でも違う文字のものがたくさん存在することが原因でした.
最終的には以下のように横棒系の文字をすべて,半角マイナスに変換することで期待通りの挙動とすることが出来ました.
const replaced = rawValue.replace(/[0-9.]/g, function (s) {
return String.fromCharCode(s.charCodeAt(0) - 65248);
})
.replace(/[--﹣−‐⁃‑‒–—﹘―⎯⏤ーー─━]/g, '-');
まとめ
今回は,しらべたら同じように苦しんでいる人が結構いたのですんなり解決できましたが,この文字周りとても複雑です.
なんで,こんなに似たような文字がたくさんあるんだと思いつつきっと歴史的経緯があるんだろうなーと.
知らないとハマることもあると思うので,将来の自分や,同じようにハマっている人に向けて備忘録的に書き残しておきます.