辞書ブラウザに「類語一括検索」機能を付ける方法

2016年07月15日

パソコン上の辞書ブラウザで使える検索方法というと、前方一致検索や全文検索などが定番ですが、新たな検索方法として、英単語の「類語一括検索」機能というものを勝手に実装してみました。辞書ブラウザに英単語を1つ入力するだけで、その類義語をまとめて串刺し検索できる機能です。AHK(AutoHotkey)を使って実装しています。

もともとは遊び半分で作ってみたプログラムなのですが、使ってみたら意外と実用的で、仕事でも手放せない機能になりましたので、スクリプトをご紹介したいと思います。今のところ、Jamming、Logophile、EBWin4の各ブラウザで動作します。よろしければお試しください。

※辞書ブラウザのプログラム自体を改造しているわけではなく、検索時の動作をAHKで制御しているだけです。

機能紹介

実際の動作イメージがこちらです。Jammingの入力エリアに「dormant」と入力してWin+Enterを押したときの様子を録画しました。通常の前方一致検索とは違って、画面左側の検索結果一覧に、dormantの類語が並んでいるのがわかります。
(Jamming自体にWin+Enterという機能があるわけではありません。あくまで勝手に追加した機能です)。

160714_jamming.gif

類語の情報はWordNetから取得しています。入力した単語のsyn(同義語)、sym(類義語)、hype(上位語)を類語とみなし、まとめて検索します。synsetの違いは考慮していません。

上の画面はたまたま検索結果にもWordNetが表示されていますが、検索対象にWordNetが入っていなくてもかまいません。

自動検索でヒットした類語は、通常の見出し語検索と同様に、画面左側に一覧表示されます。この一覧を見て、検索した単語の大まかな全体像を俯瞰しながら、それぞれの語義や例文を見比べていけるのが、この検索機能の特徴です。通常の前方一致で行う串刺し検索は、点と点を最短距離で結ぶようなイメージがあるのですが、こちらの検索は多面的なイメージで、発想が広がる感じがするのが気に入っています。

この機能は、hishidaさん作の「ebwinc」(EBWin4のコマンドライン版)と、大久保克彦さん作の「WordNet 3.1 EPWING版」を使って実現しています。辞書ブラウザに入力された単語を、自作のスクリプトで類語のリストに展開したうえで、完全一致のOR検索で辞書ブラウザに検索させるという仕組みです。

ebwincについて詳しくは、当ブログのこちらの記事をご覧ください。

必要なものと下準備

今回紹介するスクリプトを動かすには、以下が必要です(いずれも無料)。AHKとEBWin4のバージョンにご注意ください。バージョンが古いとスクリプトが動きません。

EBWin4にWordNetを登録したうえで、何番目の辞書グループの何番目の辞書として登録したかを確認しておいてください。

※LogophileやJammingを使う場合でも、EBWin4をインストールしてWordNetを登録しておく必要があります。スクリプトの中でEBWin4の付属ツールを使うためです。
(検索を実行する際にEBWin4を起動しておく必要はありません。また、LogophileやJammingにWordNetが入っていなくても大丈夫です)。

使い方

このあと紹介するAHKスクリプトを起動すると、Jamming、Logophile、EBWin4の各辞書ブラウザで類語一括検索機能を使える状態になります。その状態で、単語を入力して「Win+Enter」か「F12」を押すと、類語一括検索を実行できます。

検索モードの設定

この機能を使うときには、辞書ブラウザの検索モードを次のように設定しておいてください。

  • Jamming:「一網打尽」モードの検索設定を 190714_jamming_mode.png としてください。
    (「前」のみオンにし、一番右が「Or」の状態)
  • Logophile:検索設定を 190714_logophile_mode.png としてください。
    (「前」「完」をオンにし、横長ボタンが「Or」の状態。「字」はどちらでもよいです)
  • EBWin4:どのモードになっていても大丈夫っぽいです。

ヒット数の上限

ヒットする類語の件数や文字数が多すぎる場合、一部の類語が検索されないことがあります。上限は次のようになっています。

  • Jamming:一連の類語を並べた文字数が256文字を超える場合、超過分は検索されません。
  • Logophile:実質的に上限はないようです。
  • EBWin4:類語の数が16個を超える場合、超過分は検索されません。

検索結果の一覧にabc順で並んだ類語が、早めのアルファベットで途切れている場合、たぶんそこから先が省略されています。すべての類語を漏れなく一括検索したい場合は、実質的に上限がなさそうなLogophileを使うのがよいかもしれません。

※上で示した「256文字」「16個」という上限は、試行錯誤で割り出した値をもとに設定したものですので、辞書ブラウザの正式な仕様値とは異なるかもしれません。

スクリプト

下記のボックス内にあるのがスクリプトのコードです。この中身全体を、お好きなフォルダにお好きなファイル名で保存してください(拡張子は「.ahk」)。その際、冒頭付近にある赤字の部分は修正が必要です。お使いの環境に合わせて、次の要領で修正してください

  • 「ebwinc := "C:\Program Files (x86)\EBWin4\ebwinc.exe"」という部分
    → お使いのマシンで、EBWin4のインストール先フォルダに ebwinc.exe というファイルがあることを確認し、そのフルパスを記述してください。
  • 「param := "/G=0 /#=0"」という部分
    → EBWin4で「WordNet」を登録したグループ番号と辞書番号を記述してください。
    (「/G=○」は辞書グループ番号で、1つ目のグループなら0、2つ目なら1、3つ目なら2、…というふうに指定します。「/#=○」は辞書番号で、グループ内の1つ目の辞書なら0、2つ目なら1、…というふうに指定します)。

プログラムがおかしな動きをする可能性もあるかもしれませんので、お仕事用の環境でいきなり動かしたりするのは避けて、お時間があるときに様子を見ながら試してみてください。

GetSynonyms(word, delim := "`r`n", replacespace := " ", includehype := true, maxcnt := 0, maxlen := 0)
{
    ; ebwincのフルパスとWordNetの起動パラメータ(赤字の部分はお使いの環境に合わせて修正してください)
    ebwinc := "C:\Program Files (x86)\EBWin4\ebwinc.exe"
    param := "/G=0 /#=0"

    ; WordNetを検索
    word := Format("{:L}", Trim(word))
    clipbkup := ClipboardAll
    Clipboard := ""
    RunWait, % comspec . " /c """"" . ebwinc . """ " . param . " """ . word . """ | Clip""", , min
    result := Clipboard
    Clipboard := clipbkup

    ; 類語(syn, sym, hype)をカンマ区切りで抽出
    result := RegExReplace(result, "`a)\R+", "`r`n")
    a := StrSplit(result, "`r`n")
    synonyms := ""
    for i, s in a {
        if (RegExMatch(s, "\[syn: (.+?)\]", match)
        || RegExMatch(s, (includehype ? "(?:sim|hype)\] (.+)$" : "sim\] (.+)$"), match)) {
            synonyms := synonyms . match1 . ", "
        }
    }

    ; 整形と重複排除
    if (synonyms) {
        synonyms := RegExReplace(synonyms, ", $", "")
        synonyms := RegExReplace(synonyms, "\(.+?\)", "")
        synonyms := RegExReplace(synonyms, " ?[,;] ?", ",")
        Sort synonyms, U D,
        synonyms := word . "," . synonyms
    } else {
        synonyms := word
    }
    if (replacespace != " ") {
        synonyms := StrReplace(synonyms, " ", replacespace)
    }
    synonyms := StrReplace(synonyms, ",", delim)

    ; 最大項目数を超えた分を削除
    if ((maxcnt > 0) && (maxpos := InStr(synonyms, delim, false, 1, maxcnt))) {
        synonyms := SubStr(synonyms, 1, maxpos - 1)
    }

    ; 最大長を超えた分を削除
    if ((maxlen > 0) && (StrLen(synonyms) > maxlen)) {
        synonyms := SubStr(synonyms, 1, maxlen)
        synonyms := RegExReplace(synonyms, "^(.+)" . delim . ".+?$", "$1")
    }

    return synonyms
}

SetTitleMatchMode, 2    ; 部分一致モード

#IfWinActive ahk_class TJammingMainForm
#Enter::
F12::
    clipbkup := ClipboardAll
    ControlClick, TRichEdit5
    Clipboard := ""
    Send, +^a       ; 語句入力エリアを全選択
    Send, +^c       ; 入力語句をコピー
    ClipWait, 0.1
    Clipboard := GetSynonyms(Clipboard, " ", "-", true, 64, 256) ; 「64」はどんぶり勘定、「256」は実験結果より。
    Send, ^v        ; 変換結果を貼り付け
    Send, ^1        ; 一網打尽モードに変更
    Send, +{Enter}  ; 完全一致モードで検索
    Clipboard := clipbkup
    return
#IfWinActive

#IfWinActive ahk_class TLogophileMainForm
#Enter::
F12::
    clipbkup := ClipboardAll
    ControlClick, TEdit2
    Clipboard := ""
    Send, +^a       ; 語句入力エリアを全選択
    Send, +^c       ; 入力語句をコピー
    ClipWait, 0.1
    Clipboard := GetSynonyms(Clipboard, " ", "-", true, 256, 4096) ; 「256」「4096」ともどんぶり勘定
    Send, ^v        ; 変換結果を貼り付け
    Send, ^7        ; Or検索モードに変更
    Send, {Enter}   ; 検索
    Clipboard := clipbkup
    return
#IfWinActive

#IfWinActive EBWin
#Enter::
F12::
    clipbkup := ClipboardAll
    ControlClick, Edit1
    Clipboard := ""
    Send, ^a        ; 語句入力エリアを全選択
    Send, ^c        ; 入力語句をコピー
    ClipWait, 0.1
    Clipboard := GetSynonyms(Clipboard, "/|", "-", true, 16, 256) . "/" ; 「16」は実験結果より。「256」はどんぶり勘定
    Send, ^v        ; 変換結果を貼り付け
    Send, {Enter}   ; 検索
    Clipboard := clipbkup
    return
#IfWinActive

参考:GetSynonyms関数のパラメータ

上のスクリプトの中で、WordNetから類語情報を取得する処理は、GetSynonymsという関数にまとめています。汎用的に使い回せるように作ってありますので、他の用途でお使いいただいてもかまいません。

基本的には、類語を取得したい単語を文字列として渡すと、カンマ区切り・スペース区切り・改行区切りなどの形式で類語の一覧を文字列として得られる関数です。パラメータの意味は次のとおりです。

  • word:類語を取得したい単語
  • delim(省略可):結果の類語を区切るための区切り文字
  • replacespace(省略可):類語に含まれるスペースを何に置き換えるか
  • includehype(省略可):hype(上位語)を結果に含めるかどうか(true/false)
  • maxcnt(省略可):取得する類語の最大数(0は上限なし)
  • maxlen(省略可):取得する文字列の最大長(0は上限なし)

たとえば、次のようなコードを使うと、クリップボードに入っている単語の類語を「/」区切りでポップアップ表示できます。

MsgBox, % GetSynonyms(Clipboard, "/")
posted by 内山卓則 at 18:57 | スクリプト・プログラム