フォームに入力された全角文字とか記号、スペースを半角に変換する


DBなんかに全角文字とかスペースとか入ると検索とか集計に不便なのでユーザが登録する段階で半角に変換したいことがあったので実装した

##変換したい記号
基本的に以下に示すようなUnicodeで持ってる全角文字・記号を半角にしたい

![スクリーンショット 2016-02-02 10.09.33 AM.png](https://qiita-image-store.s3.amazonaws.com/0/17493/d729f9f2-c0c0-05f1-5e97-b4431983cd54.png "スクリーンショット 2016-02-02 10.09.33 AM.png")


今回の対象は「PCメールアドレス」だったので、全角スペースとかは全部削除するようにしてしまったのですが、基本的に上に挙げた記号はこんな感じに変換される。


![スクリーンショット 2016-02-02 10.07.42 AM.png](https://qiita-image-store.s3.amazonaws.com/0/17493/9b44dcf4-0f8e-7029-bbdd-b36ebb390c8f.png "スクリーンショット 2016-02-02 10.07.42 AM.png")

ということで、左端に示した文字コードを比較してみると16進数で0xFEE0分ずれているので全角文字からこの分シフトしてあげると半角に変換されることになる。

ということで、この「！」(0xFF01) から 「〜」(0xFF5E)の記号を変換してあげれば良い。

他に邪魔になりそうな、全角スペースとかは別途指定してあげるとこんな感じのコードになる。

```javascriopt
$(function() {
  //changeイベントはinput要素が変更を完了した時に実行
  $('.normalize').change(function(){
    //要素のvalue属性を変数に代入。
    var text = $(this).val();
    //全角英数字を対象に置き換え
    var normalizedText = text.replace(/[！-～]/g,function(s){
      return String.fromCharCode(s.charCodeAt(0)-0xFEE0);
    });
    normalizedText = jQuery.trim(normalizedText)
        .replace(/ /g,"")
        .replace(/　/g,"")
        .replace(/￥/g,"\\")
        .replace(/〜/g,"~")
        .replace(/’/g,"'")
        .replace(/”/g,"\"");
    //要素のvalue属性に変換した変換後の文字を入れる。
    $(this).val(normalizedText);
  });
});

```

ということで、該当のフォームに`.normalize`クラスを指定してあげれば実装完了ですね。

0xFF5Eの全角チルダと波ダッシュには少し悩まされましたが、次のように変換できます!

![test.gif](https://qiita-image-store.s3.amazonaws.com/0/17493/b9f0b3ad-5fd9-a159-e3c2-f8bbb0772788.gif "test.gif")

## 他の記号への対応
`[！-～]`の指定では対応できない記号(e.g. ー,ｰ,‐,–,―,−⏰,​,、,゛,)について、ブラックリスト的なものを作って対応しました。

今回は、­­正常に対応していないハイフンをUTFのハイフンに変換するリスト(replaceHyphens)と、削除対象のリスト(blackList)を生成しました。

```
var replaceTextWithList = function(BlackList, replaceCharacter, TargetText) {
  for (var i=0; i<BlackList.length; i++){
    var tmp = unescape(BlackList[i]);
    if (TargetText.match(tmp)){
      TargetText = TargetText.replace(tmp, replaceCharacter);
    }
  }
  return TargetText;
};

$(function() {
  //changeイベントはinput要素が変更を完了した時に実行
  $('.normalize').change(function(){
    //要素のvalue属性を変数に代入。
    var text = $(this).val();
    //全角英数字を対象に置き換え
    var normalizedText = text.replace(/[！-～]/g,function(s){
      return String.fromCharCode(s.charCodeAt(0)-0xFEE0);
    });
    normalizedText = jQuery.trim(normalizedText)
        .replace(/ /g,"")
        .replace(/　/g,"")
        .replace(/￥/g,"\\")
        .replace(/〜/g,"~")
        .replace(/’/g,"'")
        .replace(/”/g,"\"");
    
    var replaceHyphens = ["%u30FC", "%uFF70", "%u2010", "%u2013", "%u2015", "%u2212"];
    var blackList      = ["%u23F0", "%u200B", "%u3001", "%u309B", "%u200B"];    

    // unicode のハイフンを変換    
    normalizedText = replaceTextWithList(replaceHyphens, '-', normalizedText);
    // 不要な記号は削除
    normalizedText = replaceTextWithList(blackList, '', normalizedText);

    //要素のvalue属性に変換した変換後の文字を入れる。
    $(this).val(normalizedText);
  });
});
```

きれいに変換できました。これで、DBに変な記号が入るのを防止できる！

![aaa.gif](https://qiita-image-store.s3.amazonaws.com/0/17493/87cc1b3b-023a-3374-1ab6-285f5649f277.gif "aaa.gif")

関数にしたのでリストの内容や、置換先の文字列を入れ替えるだけでカスタマイズできますね！便利便利！

##参考URL
- [JavaScript で英数字や記号を全角から半角へ変換する方法](http://jquery.nj-clucker.com/change-double-byte-to-half-width/)
- [波ダッシュ、全角チルダ問題まとめ](http://qiita.com/kasei-san/items/3ce2249f0a1c1af1cbd2)