😺

【JS/TS】全角ひらがな→全角カタカナ→半角カタカナ

2023/02/09に公開

コード

TypeScript Playgroundにコピペしてすぐ動作確認できます👍

// 全角ひらがな → 全角カタカナ
const hiraToKana = (str: string) => str.replace(/[\u3041-\u3096]/g, (match) => String.fromCharCode(match.charCodeAt(0) + 0x60));
// 全角の濁点&半濁点 → 半角の濁点&半濁点
const narrowDakuten = (str: string) => str.replace(/\u309B|\u3099/g, '\uFF9E').replace(/\u309C|\u309A/g, '\uFF9F');
// 全角カタカナ → 半角カタカナ
const  narrowKatakana = (str: string) => {
  const convertMap = {: 'ァ',: 'ィ',: 'ゥ',: 'ェ',: 'ォ',: 'ャ',: 'ュ',: 'ョ',: 'ッ',: 'カ',: 'ケ',: 'ワ',: 'ー',: 'ア',: 'イ',: 'ウ',: 'エ',: 'オ',: 'カ',: 'キ',: 'ク',: 'ケ',: 'コ',: 'サ',: 'シ',: 'ス',: 'セ',: 'ソ',: 'タ',: 'チ',: 'ツ',: 'テ',: 'ト',: 'ナ',: 'ニ',: 'ヌ',: 'ネ',: 'ノ',: 'ハ',: 'ヒ',: 'フ',: 'ヘ',: 'ホ',: 'マ',: 'ミ',: 'ム',: 'メ',: 'モ',: 'ヤ',: 'ユ',: 'ヨ',: 'ラ',: 'リ',: 'ル',: 'レ',: 'ロ',: 'ワ',: 'ン',: 'イ',: 'エ',: 'ヲ',: 'ガ',: 'ギ',: 'グ',: 'ゲ',: 'ゴ',: 'ザ',: 'ジ',: 'ズ',: 'ゼ',: 'ゾ',: 'ダ',: 'ヂ',: 'ヅ',: 'デ',: 'ド',: 'バ',: 'ビ',: 'ブ',: 'ベ',: 'ボ',: 'パ',: 'ピ',: 'プ',: 'ペ',: 'ポ',: 'ヷ',: 'イ゙',: 'ヴ',: 'エ゙',: 'ヺ'
  };

  for (const [wideKana, narrowKana] of Object.entries(convertMap)) {
    str = str.replace(new RegExp(wideKana, 'g'), narrowKana);
  }
  return str;
}

const hiragana = 'あいうえおがぎぐげご ゛゜';
const result1 = hiraToKana(hiragana);
const result2 = narrowDakuten(result1);
const result3 = narrowKatakana(result2);

console.log(hiragana); // "あいうえおがぎぐげご ゛゜";
console.log(result1);  // "アイウエオガギグゲゴ ゛゜" 
console.log(result2);  // "アイウエオガギグゲゴ ゙゚" 
console.log(result3);  // "アイウエオガギグゲゴ ゙゚" 

全角ひらがな → 全角カタカナ

const hiragana = 'あいうえお';
const katakana = hiraToKana(hiragana);// アイウエオ

function hiraToKana(str: string) {
    return str.replace(/[\u3041-\u3096]/g, function(match) {
        var chr = match.charCodeAt(0) + 0x60;
        return String.fromCharCode(chr);
    });
}

【\u3041-\u3096】って何?

「ぁ(U+3041)」から「け(U+3096)」までのUnicode from [Hiragana(Unicode block)]

+ 0x60 って何?

全角ひらがな と 全角カタカナ のUnicodeはちょうど【0x60】の等しい間隔になっている。
「あ(U+3042)」-「ア(U+30A2)」= 4 - A(10) = 6
「け(U+3051)」-「ケ(U+30B1)」= 5 - B(11) = 6

なので、この間隔をなくせば全角ひらがな ⇔ 全角カタカナの変換が可能。

全角カタカナ → 半角カタカナ

先ほどの全角ひらがな⇔全角カタカナのように、Unicodeが等しい間隔になっているわけではないので、地道にマッピングを作成してあげる必要がある。

Discussion