JavaScript で英数字や記号を全角から半角へ変換する方法
ブラウザ上で半角入力の制御は CSS の ime-mode プロパティが存在します。しかしこれは Internet Exporer 独自のものなので、Chrome ブラウザなど対応していないブラウザも存在します。
全角入力を拒否するような制御を JavaScript に組み込むことも可能ですが、半角に直してもう一度同じ内容を入力させる仕様は最適な対応方法ではないと考えています。
そこでユーザビリティを損なわず、故意ではない全角入力を許容するために、英数字や記号を全角から半角に変換する処理を提案させていただきます。
全角から半角へ変換するメリット
ある特定項目のデータを半角で統一することで、生まれるメリットもたくさんあります。例えば、検索画面で対象となるデータは、全角と半角が混在していると部分一致の条件を拡張しなくてはいけないので抽出するのが大変です。
Oracle であれば TO_SINGLE_BYTE 関数を使って変換処理することも可能ですが、検索対象の母数が大きいとパフォーマンスにも影響します。予め統一した状態で登録しておけば、効率よく検索できるようになるでしょう。
特に textarea のような長文入力できる項目の場合、別のデータからコピー&ペーストして入力されることもあるため、ユーザー側で意識的に半角に書き換えることもしないでしょう。もし自動的に半角変換されることが利用者に伝わっていれば、安心して全角と半角が混在したデータを入力できるので、システム全体の利便性の向上を見込むこともできます。
全角から半角に変換する – 英数/記号
JavaScript の変換処理と言えば replace 関数です。一文字ずつ判断して変換処理を掛ければ、半角化することができます。しかし、そんな冗長なループ処理のプログラムはセンスがありません。ここは replace 関数と 正規表現 を組み合わせて変換を行うとスマートな処理になります。
文字コードをシフトさせて変換する
英数記号の文字コードは半角と全角で同じ並びをしています。それぞれの文字コードをご覧ください。
半角英数記号 – Unicode
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
U+0020 | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | |
U+0030 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
U+0040 | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
U+0050 | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
U+0060 | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
U+0070 | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | |
全角英数記号 – Unicode
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
U+FF00 | | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / |
U+FF10 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
U+FF20 | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
U+FF30 | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
U+FF40 | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
U+FF50 | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | ⦅ |
例えばエクスクラメーション「!」の場合、半角の U+0021 と全角の U+FF01 でコード値が 0xFEE0 ずれています。この文字コードのずれている分をシフトしてあげることで、「!」から「~」の範囲で全角から半角の変換を実現させることができます。
ではプログラムで実装してみましょう。
/** * 全角から半角への変革関数 * 入力値の英数記号を半角変換して返却 * [引数] strVal: 入力値 * [返却値] String(): 半角変換された文字列 */ function toHalfWidth(strVal){ // 半角変換 var halfVal = strVal.replace(/[!-~]/g, function( tmpStr ) { // 文字コードをシフト return String.fromCharCode( tmpStr.charCodeAt(0) - 0xFEE0 ); } ); return halfVal; }
とてもシンプルな処理ができあがりました。
しかしこれでは不完全です。どこに問題があるのか箇条書きでまとめておきましょう。
- 全角のダブルクォート・シングルクォート・バッククォートの文字が異なっている
- 全角の「¥」が上記のコード内に存在しない
- 全角スペースが対象外になっている
- この処理で変換されるのは「~」であり「〜」ではない。(ブラウザ上では判別しづらいが文字コードが違う)まれに「〜」が入力される場合があるため、別途変換が必要。
全角「・」を半角「・」に変換する処理も含まれていませんが、半角「・」は半角カナに属するのでここでは変換処理の対象としていません。
つまり、これらの文字コードシフトで対応できない文字の処理を加えれば完成です。
/** * 全角から半角への変革関数 * 入力値の英数記号を半角変換して返却 * [引数] strVal: 入力値 * [返却値] String(): 半角変換された文字列 */ function toHalfWidth(strVal){ // 半角変換 var halfVal = strVal.replace(/[!-~]/g, function( tmpStr ) { // 文字コードをシフト return String.fromCharCode( tmpStr.charCodeAt(0) - 0xFEE0 ); } ); // 文字コードシフトで対応できない文字の変換 return halfVal.replace(/”/g, "\"") .replace(/’/g, "'") .replace(/‘/g, "`") .replace(/¥/g, "\\") .replace(/ /g, " ") .replace(/〜/g, "~"); }
それではプログラムの動作を確認してみましょう。
全角英数記号を半角変換処理サンプル
次のテキストエリアに全角文字を入力し、フォーカスが外れると半角変換を行います。
もし一部の半角ではなく全角に統一したい記号があれば、正規表現から該当部分を除いて、全角変換する replace 処理を加えれば大丈夫です。基本的にはこのコードをベースに改修できると思います。
以上、JavaScript で英数字や記号を全角から半角へ変換する方法でした。