LANG SELRCT

コードを書く場所についてはこちら

2017年12月2日土曜日

全角ひらがな⇔全角カタカナ⇔半角カタカナ変換


ひらがなとカタカナの相互変換をしたいと思ったときに
Web上で変換できる便利なツールは見つかりますが
手元のコードで実現したくなって書いたコードです


ついでに半角カタカナも変換しようとしたら思いのほか大変で
やめようかと思いましたが
いろいろ試している内に上手く変換できたので
それも含めてコード.gsに書きました

半角カタカナは濁点(゛)と半濁点(゜)が一文字にカウントされてしまい
配列の番号がズレて上手くいかない
「ガ」は「カ」と「゙」に分かれてしまうというハマりどころがありました


文字コードで変換するやり方もあると思いますが
ここではすべての文字を配列で用意しておいて(var hira, kana, hankana)
配列の中で一致するときの番号を見て変換するやり方を書きました



コード.gs
var hira = ["あ", "い", "う", "え", "お", "か", "き", "く", "け", "こ", "さ", "し", "す", "せ", "そ", "た", "ち", "つ", "て", "と", "な", "に", "ぬ", "ね", "の", "は", "ひ", "ふ", "へ", "ほ", "ま", "み", "む", "め", "も", "や", "ゆ", "よ", "ら", "り", "る", "れ", "ろ", "わ", "を", "ん", "が", "ぎ", "ぐ", "げ", "ご", "ざ", "じ", "ず", "ぜ", "ぞ", "だ", "ぢ", "づ", "で", "ど", "ば", "び", "ふ", "べ", "ぼ", "ぱ", "ぴ", "ぴ", "ぺ", "ぽ", "ぁ", "ぃ", "ぅ", "ぇ", "ぉ", "ゃ", "ゅ", "ょ", "っ", "ゔ"];
var kana = ["ア", "イ", "ウ", "エ", "オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", "ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ワ", "ヲ", "ン", "ガ", "ギ", "グ", "ゲ", "ゴ", "ザ", "ジ", "ズ", "ゼ", "ゾ", "ダ", "ヂ", "ヅ", "デ", "ド", "バ", "ビ", "フ", "ベ", "ボ", "パ", "ピ", "ピ", "ペ", "ポ", "ァ", "ィ", "ゥ", "ェ", "ォ", "ャ", "ュ", "ョ", "ッ", "ヴ"];
var hankana = ["ア", "イ", "ウ", "エ", "オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", "ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ワ", "ヲ", "ン", "ガ", "ギ", "グ", "ゲ", "ゴ", "ザ", "ジ", "ズ", "ゼ", "ゾ", "ダ", "ヂ", "ヅ", "デ", "ド", "バ", "ビ", "ブ", "ベ", "ボ", "パ", "ピ", "プ", "ペ", "ポ", "ァ", "ィ", "ゥ", "ェ", "ォ", "ャ", "ュ", "ョ", "ッ", "ヴ"];
function hira_kana_hankana() {
  var text = "デジャヴュ"; 
  var input = hankana;
  var output = hira;

  var result = "";
  var array = [];
  for (var i = 0; i < text.length; i++) {
    if (text[i] == "゙" || text[i] == "゚") {
      array[array.length - 1] = (text[i - 1] + text[i]);
    } else {
      array.push(text[i]);
    }
    Logger.log(array);
  }
  for (var j = 0; j < array.length; j++) {
    var index = input.indexOf(array[j]);
    if (index == -1) {
      result = result + array[j];
    } else {
      result = result + output[index];
    }
    Logger.log(result);
  }
  Logger.log(result)
}
意訳.gs
ひらがなを用意する
カタカナを用意する
半角カタカナを用意する
この機能は以下を実行する
変換したいテキストをtextに入れて(例ではデジャヴュ)
変換前の状態を設定して(hira, kana, hanakana)
変換後の状態を設定して

変換結果を入れるresultという入れ物を用意して
半角カナの濁音・半濁音の結合用にarrayという入れ物を用意して
textの文字数分以下を繰り返す
もし文字が濁点または半濁点なら
arrayの最後の文字を濁点・半濁点付きの文字で上書き
濁点・半濁点じゃなければ
arrayにそのまま追加する

arrayの文字を段階的にログに出す

arrayに入っている文字数分以下を繰り返す
文字の一覧から、見つけたい文字が何番目にあるか探して
見つからなかったら
そのままresultに足し
見つかったら
resultに変換後の文字を足す

resultの文字を段階的にログに出す

最終的なresultをログに出す




おまけ

上のコードを改造して
スプレッドシートに変換結果を書き出すコードも書きました

この例ではA列のひらがなをあらかじめ入力しておき
set_values()を実行すると
B列にカタカナ変換された文字が入力され
C列に半角カタカナ変換された文字が入力されます


var kana_result = hira_kana_hankana(hira, kana, values[i][0]);
ここで変換前はひらがな(hira)で、変換後はカタカナ(kana)で、A列で取得した一行ごとのテキストvalues[i][0]をhira_kana_hankanaに渡して結果を取得しています

半角カタカナも同様に
var hankana_result = hira_kana_hankana(hira, hankana, values[i][0]);
変換前はひらがなで、変換後は半角カタカナで、A列で取得した一行ごとのテキストを渡して結果を取得しています



コード.gs
function set_values(){
  var sh = SpreadsheetApp.getActiveSheet();
  var lastrow = sh.getLastRow();
  var range = sh.getRange("A2:A" + lastrow);
  var values = range.getValues();  
  for(var i = 0; i < values.length; i++){
     var row = i + 1;
     var kana_result = hira_kana_hankana(hira, kana, values[i][0]);
     var hankana_result = hira_kana_hankana(hira, hankana, values[i][0]);
     sh.getRange("B" + (row + 1)).setValue(kana_result);
     sh.getRange("C" + (row + 1)).setValue(hankana_result);
  } 
}

var hira = ["あ", "い", "う", "え", "お", "か", "き", "く", "け", "こ", "さ", "し", "す", "せ", "そ", "た", "ち", "つ", "て", "と", "な", "に", "ぬ", "ね", "の", "は", "ひ", "ふ", "へ", "ほ", "ま", "み", "む", "め", "も", "や", "ゆ", "よ", "ら", "り", "る", "れ", "ろ", "わ", "を", "ん", "が", "ぎ", "ぐ", "げ", "ご", "ざ", "じ", "ず", "ぜ", "ぞ", "だ", "ぢ", "づ", "で", "ど", "ば", "び", "ふ", "べ", "ぼ", "ぱ", "ぴ", "ぴ", "ぺ", "ぽ", "ぁ", "ぃ", "ぅ", "ぇ", "ぉ", "ゃ", "ゅ", "ょ", "っ", "ゔ"];
var kana = ["ア", "イ", "ウ", "エ", "オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", "ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ワ", "ヲ", "ン", "ガ", "ギ", "グ", "ゲ", "ゴ", "ザ", "ジ", "ズ", "ゼ", "ゾ", "ダ", "ヂ", "ヅ", "デ", "ド", "バ", "ビ", "フ", "ベ", "ボ", "パ", "ピ", "ピ", "ペ", "ポ", "ァ", "ィ", "ゥ", "ェ", "ォ", "ャ", "ュ", "ョ", "ッ", "ヴ"];
var hankana = ["ア", "イ", "ウ", "エ", "オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", "ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ワ", "ヲ", "ン", "ガ", "ギ", "グ", "ゲ", "ゴ", "ザ", "ジ", "ズ", "ゼ", "ゾ", "ダ", "ヂ", "ヅ", "デ", "ド", "バ", "ビ", "ブ", "ベ", "ボ", "パ", "ピ", "プ", "ペ", "ポ", "ァ", "ィ", "ゥ", "ェ", "ォ", "ャ", "ュ", "ョ", "ッ", "ヴ"];
function hira_kana_hankana(input, output, text) {
  var result = "";
  var array = [];
  for (var i = 0; i < text.length; i++) {
    if (text[i] == "゙" || text[i] == "゚") {
      array[array.length - 1] = (text[i - 1] + text[i]);
    } else {
      array.push(text[i]);
    }
  }
  for (var j = 0; j < array.length; j++) {
    var index = input.indexOf(array[j]);
    if (index == -1) {
      result = result + array[j];
    } else {
      result = result + output[index];
    }
  }
  return result;
}