PHPで最長一致検索や一括置換、共通接頭辞検索(common prefix search)をするためのライブラリ imdr を公開します。
ダウンロード:imdr 1.0(ZIPファイル:2KB)
たとえば中国語の文章をピンインに変換する場合、文章に含まれる単語を調べ、対応するピンインを取得する必要があります。元の文が「收发电子邮件」だとして、1文字目の「收」で始まる単語を辞書データベースから取得し、それがこの文章に含まれているかひとつひとつ調べていくことになります。このとき、長い単語から短い単語の順(降順)で検索を行わないと「收发」の正しいピンインが得られません。「发」には「fa1」と「fa4」という2つの読みがあり、1文字単位で検索を行うとどちらの音が当てはまるのか分からないからです。
問題は、この辞書データベースを調べるという処理に時間がかかる点です。オンライン辞書の北辞郎には「收」で始まる単語が264件収録されています。「发」で始まる単語は472件、「电」や「子」にも多くの単語が収録されています。「收发电子邮件」というたかだか6文字のために軽く数千回は辞書にアクセスすることになります。ちょっとした長さのテキストになると、あっという間にシステムが固まるでしょう。
imdrはこうした問題を回避し、文章に含まれる単語を効率よく検索することができるライブラリです。わずか6KB、200行ほどのファイルをrequireするだけで使えます。
require_once 'imdr.php';
$test = new imdr();
#addで見出しに対応するデータを登録する
#今回は漢字と対応するピンイン
$test->add("收", "shou1");
$test->add("发", "fa1/fa4");
$test->add("收发", "shou1fa1");
$test->add("电", "dian4");
$test->add("子", "zi3");
$test->add("电子", "dian4zi3");
$test->add("邮", "you2");
$test->add("件", "jian4");
$test->add("邮件", "you2jian4");
$test->add("电子邮件", "dian4zi3you2jian4");
#登録内容を確認
$test->showMember();
Array
(
[收0] => 1
[发0] => 2
[发1] => 3
[电0] => 4
[子0] => 5
[子4] => 6
[邮0] => 7
[件0] => 8
[件7] => 9
[邮6] => 10
[件10] => 11
)
Array
(
[1] => shou1
[2] => fa1/fa4
[3] => shou1fa1
[4] => dian4
[5] => zi3
[6] => dian4zi3
[7] => you2
[8] => jian4
[9] => you2jian4
[11] => dian4zi3you2jian4
)
#文章を読み込ませて最長単語に対応するデータを取得(返値は二重配列)
$res = $test->getpair("收发电子邮件");
print_r($res);
Array
(
[0] => Array
(
[0] => 收发
[1] => shou1fa1
)
[1] => Array
(
[0] => 电子邮件
[1] => dian4zi3you2jian4
)
)
#文章の先頭から共通接頭辞を取得(返値は配列)
$res = $test->commonprefix("收发电子邮件");
Array
(
[0] => 收
[1] => 收发
)
#最長の単語に対応するピンインに置き換える(返値は配列)
$res = $test->replace("收发电子邮件");
Array
(
[0] => shou1fa1
[1] => dian4zi3you2jian4
)
imdrは、北辞郎の漢字変換や一括検索で使われており、これらのページでは数万語のデータを扱っています。一般的な用途であれば問題なく使えると思います。
メンバメソッドについては以下を参照下さい。
add($word, $value)
imdrに単語($word)とそれに対応する値($value)を登録します。
remove($word)
登録されている単語($word)とそれに対応する値($value)をimdrから削除します。
commonprefix($target)
$targetに含まれる共通接頭辞を取得する。返値は共通接頭辞の配列。
replace($text)
$textに含まれる最長接頭辞を対応する値で置換する。返値は置換後の値の配列。
getpair($text)
$textに含まれる最長接頭辞と対応する値のペアを取得する。返値は二重配列(上記の例を参照)。
generate($fn)
タブ区切りのデータが保存されたファイル($fn)からデータをまとめて登録する。ファイルの文字コードはUTF-8とし、単語<タブ>値<改行>の形式であること。
save($fn)
imdrをファイル($fn)に保存する。
load($fn)
imdrにファイルからデータを読み込む。
showMember()
imdrのメンバ変数の状態を出力する。
※200行程度のライブラリですので上記以外はソースを参照下さい。なお、imdr は「芋づる」の略です。
履歴
2021年10月03日 Ver1.01 バグ修正、メソッド名変更(getout->getvalue)、メソッド追加(getprefix)