LANG SELRCT

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

2017年12月2日土曜日

MECAPIを利用して漢字にフリガナをふる



MECAPI - MeCab Web Service (MeCab API)
http://yapi.ta2o.net/apis/mecapi.cgi

↑こちらのMECAPI を利用s漢字にフリガナをふる
ということをスプレッドシートのデータに対してやってみた時に書いたコードです

※APIはたたきすぎないようにしましょう

このAPIを利用すると以下のように結果を取得することができるようです


http://yapi.ta2o.net/apis/mecapi.cgi?sentence=形態素解析

↑こういう感じでブラウザのアドレス欄に入力してreturnキーを押すだけで

↓こういう結果が返ってくる


http://yapi.ta2o.net/apis/mecapi.cgi?sentence=形態素解析&format=json

↑&format=jsonを追加すると

↓json形式でも取得ができる



コード.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 + 2;
     var kana_result = get_kana(values[i][0]);
     sh.getRange("B" + row).setValue(kana_result);
  } 
}

function get_kana(text) {
  text = encodeURIComponent(text);
  var url = "http://yapi.ta2o.net/apis/mecapi.cgi?sentence=" + text + "&format=json";
  var response = UrlFetchApp.fetch(url).getContentText();
  var jobj = JSON.parse(response);
  var result = "";
  for(var i = 0; i < jobj.length; i++){
    var kana = jobj[i]["feature"].split(",")[7];
    if(kana == null){
    var kana = jobj[i]["surface"];
    }
    result = result + kana;
  }
  return result;
}
意訳.gs
この機能は以下を実行する
今開いているシートを取得して
値が入っている最終行を取得して
A列で値が入っている最終行を範囲指定して
すべての値を取得して
値の数だけ以下の処理を繰り返す
rowを行数として2行目から入力したいので+2
A列の行ごとの値をget_kanaに送って結果を取得して
B列に入力する



この機能は以下を実行する
textをエンコードして
urlを指定して
取得して
JSONをオブジェクトに変換し
結果を入れるためのresultという入れ物を用意して
オブジェクトの数だけ以下を繰り返す
featureの7番を取得し
もしnullなら
surfaceの値を取得する

resultに結果を足していき

返す



試してみる


今回用意したデータ

都道府県の漢字にフリガナをふっていきます

都道府県フリガナ
北海道
青森県
岩手県
宮城県
秋田県
山形県
福島県
茨城県
栃木県
群馬県
埼玉県
千葉県
東京都
神奈川県
新潟県
富山県
石川県
福井県
山梨県
長野県
岐阜県
静岡県
愛知県
三重県
滋賀県
京都府
大阪府
兵庫県
奈良県
和歌山県
鳥取県
島根県
岡山県
広島県
山口県
徳島県
香川県
愛媛県
高知県
福岡県
佐賀県
長崎県
熊本県
大分県
宮崎県
鹿児島県
沖縄県


コード.gsのset_values()を実行すると

上から順にフリガナが入力されていきます

都道府県フリガナ
北海道ホッカイドウ
青森県アオモリケン
岩手県イワテケン
宮城県ミヤギケン
秋田県アキタケン
山形県ヤマガタケン
福島県フクシマケン
茨城県イバラキケン
栃木県トチギケン
群馬県グンマケン
埼玉県サイタマケン
千葉県チバケン
東京都トウキョウト
神奈川県カナガワケン
新潟県ニイガタケン
富山県トヤマケン
石川県イシカワケン
福井県フクイケン
山梨県ヤマナシケン
長野県ナガノケン
岐阜県ギフケン
静岡県シズオカケン
愛知県アイチケン
三重県ミエケン
滋賀県シガケン
京都府キョウトフ
大阪府オオサカフ
兵庫県ヒョウゴケン
奈良県ナラケン
和歌山県ワカヤマケン
鳥取県トットリケン
島根県シマネケン
岡山県オカヤマケン
広島県ヒロシマケン
山口県ヤマグチケン
徳島県トクシマケン
香川県カガワケン
愛媛県エヒメケン
高知県コウチケン
福岡県フクオカケン
佐賀県サガケン
長崎県ナガサキケン
熊本県クマモトケン
大分県オオイタケン
宮崎県ミヤザキケン
鹿児島県カゴシマケン
沖縄県オキナワケン



おまけ


ひらがなでふりがなをふりたい場合


以下の記事で書いたコードを加えるとひらがなで入力できます

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


コード.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 + 2;
     var kana_result = get_kana(values[i][0]);
     var hira_result = hira_kana_hankana(kana, hira, kana_result);
     sh.getRange("B" + row).setValue(hira_result);
  } 
}

function get_kana(text) {
  text = encodeURIComponent(text);
  var url = "http://yapi.ta2o.net/apis/mecapi.cgi?sentence=" + text + "&format=json";
  var response = UrlFetchApp.fetch(url).getContentText();
  var jobj = JSON.parse(response);
  Logger.log(response);
  var result = "";
  for(var i = 0; i < jobj.length; i++){
    var kana = jobj[i]["feature"].split(",")[7];
    if(kana == null){
    var kana = jobj[i]["surface"];
    }
    result = result + kana;
  }
  Logger.log(result);
  return result;
}

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




コード.gsのset_values()を実行すると
B列にひらがなのふりがなが入力されます



おまけ2


EXCELのPHONETIC関数みたいに使ってみる

カタカナにしたい場合はget_kana(text)を使えるので

例えばA2の北海道をカタカナにしたい場合はB2に

=get_kana(A2)

とすればホッカイドウと変換されます




おまけ3


ひらがなや半角カタカナに変換したい場合は
半角カタカナの一覧と
以下のようなコードを追加するとできます

function get_hira(text){
  var kana_result = get_kana(text);
  var hira_result = hira_kana_hankana(kana, hira, kana_result);
  return hira_result;
}

function get_hankana(text){
  var kana_result = get_kana(text);
  var hankana_result = hira_kana_hankana(kana, hankana, kana_result);
  return hankana_result;
}

ついでにset_values() を実行したときに
B列にカタカナ、C列にひらがな、D列に半角カタカナを入力するようにしたコードです


コード.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 + 2;
     var kana_result = get_kana(values[i][0]);
     var hira_result = hira_kana_hankana(kana, hira, kana_result);
     var hankana_result = hira_kana_hankana(kana, hankana, kana_result);
     sh.getRange("B" + row).setValue(kana_result);
     sh.getRange("C" + row).setValue(hira_result);
     sh.getRange("D" + row).setValue(hankana_result);
  } 
}

function get_kana(text) {
  text = encodeURIComponent(text);
  var url = "http://yapi.ta2o.net/apis/mecapi.cgi?sentence=" + text + "&format=json";
  var response = UrlFetchApp.fetch(url).getContentText();
  var jobj = JSON.parse(response);
  Logger.log(response);
  var result = "";
  for(var i = 0; i < jobj.length; i++){
    var kana = jobj[i]["feature"].split(",")[7];
    if(kana == null){
    var kana = jobj[i]["surface"];
    }
    result = result + kana;
  }
  Logger.log(result);
  return result;
}

function get_hira(text){
  var kana_result = get_kana(text);
  var hira_result = hira_kana_hankana(kana, hira, kana_result);
  return hira_result;
}

function get_hankana(text){
  var kana_result = get_kana(text);
  var hankana_result = hira_kana_hankana(kana, hankana, kana_result);
  return 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;
}


set_values() を実行すると


B2に=get_hira(A2)を入力すると


B2に=get_hankana(A2)を入力すると



APIをたたく回数を減らす


上の例では一行毎にAPIをたたいていましたが
一回ですべての結果を取得する方が効率的なのでそのコードも書いてみました


コード.gs
function to_kana(){
  var text = get_values();
  var result = get_kana(text);
  var array = create_array(result);
  set_values(array);
}

function get_values(){
  var sheet = SpreadsheetApp.getActiveSheet();
  var lastrow = sheet.getLastRow();
  var range = sheet.getRange("A2:A" + lastrow);
  var values = range.getValues();
  var text = "";
  for(var i = 0; i < values.length; i++){
    var text = text + values[i] + " ";
  } 
  return text;
}

function get_kana(text) {
  text = encodeURIComponent(text);
  var url = "http://yapi.ta2o.net/apis/mecapi.cgi?sentence=" + text + "&format=json";
  var response = UrlFetchApp.fetch(url).getContentText();
  var jobj = JSON.parse(response);
  var result = "";
  for(var i = 0; i < jobj.length; i++){
    var kana = jobj[i]["feature"].split(",")[7];
    if(kana == null){
    var kana = jobj[i]["surface"];
    }
    result = result + kana;
  }
  return result;
}

function create_array(result){
 var array = [];
  var result_split = result.split(" ");
  for(var i = 0; i < result_split.length; i++){
   array.push([result_split[i]]);
  }
  return array;
}

function set_values(array){
  var sheet = SpreadsheetApp.getActiveSheet();
  var start_row = 2;
  var start_col = 2;
  var num_rows = array.length;
  var num_cols = 1;
  var range = sheet.getRange(start_row, start_col, num_rows, num_cols);
  range.setValues(array); 
}
意訳
この処理は以下の処理を実行する
値を取得してtextに入れて
カナに変換した結果をresultに入れて
set_valuesに渡すために配列を作って
シートに入力する


この処理は以下の処理を実行する
開いているシートを取得して
データの入っている最終行を取得して
A2からA列の最終行までを範囲指定して
すべての値を取得する
値を全角スペースでつないだ結果を入れる入れ物を用意して
値の数だけ以下を繰り返す
値に全角スペースを付けてtextに足す

すべての値が全角スペースで繋がったtextを返す


この処理は以下の処理を実行する
渡されたtextをエンコードしてから
mecapiのurlにsentence以下を追加して
APIをたたいた結果を取得して
JSONをオブジェクトに変換し
カナ変換の結果を入れるresultという入れ物を用意して
オブジェクトの中身の数だけ以下を繰り返す
featureの7番目を取得し(カタカナに変換された文字)
もしnullなら(変換されなかったら)
surfaceの値を取得する(入力したそのままの値)

resultに結果を足していき

すべての結果が入ったresultを返す


この処理は以下の処理を実行する
入れ物を用意する
渡されたresultの値を全角スペースで区切って
区切った数だけ以下を繰り返す
arrayにひとつずつ追加していく

配列化されたarrayを返す


この処理は以下を実行する
開いているシートを取得して
入力するのは2行目から
入力する列は2列目
入力する行数をarrayの長さから取得して
入力する列数は1列
入力を開始する行, 入力を開始する列, 入力する行数, 入力する列数で範囲を指定して
arrayのデータを入力する




参考サイト

MeCab
http://taku910.github.io/mecab/

MECAPI - MeCab Web Service (MeCab API)
http://yapi.ta2o.net/apis/mecapi.cgi