MySQLのサンプルのラテン文字でロシア語のテキスト(名前)のさまざまな音訳を検索する

実際、私は平凡な仕事に出くわしました-ラテン文字で書かれたフルネームのデータが大量にあるデータベースがあります。 多くの場合、非常に読み書きができず、予想外に音訳されます。 GOST 7.79(ISO 9)のようですが、実際には常に尊重されるとは限りません。

タスク-ラテン文字のレコード(通常はフルネーム)を含むデータベースがあります。 悪いラテン系のアルファベット。 Webアプリケーションのロシア語の検索部分文字列からデータベース(MySQL)からエントリを選択する必要があり、ラテン語のアルファベットに音訳されているようです。





最初の考えは、ラテン文字で元のフレーズの可能なスペルを含む配列を返す関数を書くことです。

ソース1、平凡な文字列を音訳する方法を確認できます
print_r (r2e ("     ")); function r2e ($txt) { $r=array(mb_strtolower($txt,"windows-1251")); $r=r2es($r,"//i",array("x","ks","cs")); $r=r2es($r,"//i",array("ey","ei")); $r=r2es($r,"//i",array("ov","off")); $r=r2es($r,"//i",array("a")); $r=r2es($r,"//i",array("b")); $r=r2es($r,"//i",array("v","w")); $r=r2es($r,"//i",array("g")); $r=r2es($r,"//i",array("d")); $r=r2es($r,"//i",array("e")); $r=r2es($r,"//i",array("yo","jo")); $r=r2es($r,"//i",array("zh","z")); $r=r2es($r,"//i",array("z","s")); $r=r2es($r,"//i",array("i")); $r=r2es($r,"//i",array("j","y")); $r=r2es($r,"//i",array("k","c")); $r=r2es($r,"//i",array("l")); $r=r2es($r,"//i",array("m")); $r=r2es($r,"//i",array("n")); $r=r2es($r,"//i",array("o")); $r=r2es($r,"//i",array("p")); $r=r2es($r,"//i",array("r")); $r=r2es($r,"//i",array("s")); $r=r2es($r,"//i",array("t")); $r=r2es($r,"//i",array("u")); $r=r2es($r,"//i",array("f")); $r=r2es($r,"//i",array("h","kh")); $r=r2es($r,"//i",array("c","ts")); $r=r2es($r,"//i",array("ch")); $r=r2es($r,"//i",array("sh")); $r=r2es($r,"//i",array("shch","sch","sh")); $r=r2es($r,"//i",array("")); $r=r2es($r,"//i",array("y")); $r=r2es($r,"//i",array("")); $r=r2es($r,"//i",array("e")); $r=r2es($r,"//i",array("u","yu","ju")); $r=r2es($r,"//i",array("ya","ja")); return $r; } function r2es ($var, $pattern, $splits) { $sp=array(); $nsp=array(); foreach ($var as $v) if (preg_match($pattern,$v)) foreach ($splits as $split) $sp=array_merge($sp,array(preg_replace($pattern,$split,$v))); else $nsp=array_merge($nsp,array($v)); return array_merge($sp,$nsp); }
      
      









例1の出力配列の内容
配列



[0] => ochen prostaya fraza na russkom yazyke

[1] => ochen prostaja fraza na russkom jazyke

[2] => ochen prostaya fraza na russcom yazyce

[3] => ochen prostaja fraza na russcom jazyce

[4] => ochen prostaya frasa na russkom yasyke

[5] => ochen prostaja frasa na russkom jasyke

[6] => ochen prostaya frasa na russcom yasyce

[7] => ochen prostaja frasa na russcom jasyce







情報を提供していてもうまく機能しているようですが、結果の配列もフォームのリクエストへのアペンデージで接着する必要があります

 $sqlstr = "SELECT <smth> FROM <smwhr> WHERE searchField LIKE '%" . implode("%' OR searchField LIKE '%",$result) . "%'"; ,     $sqlstr = "SELECT <smth> FROM <smwhr> WHERE searchField LIKE '" . implode("' OR searchField LIKE '",$result) . "'";
      
      







さて、技術的には、SQLクエリが時間によって非常に簡単に拡張できることを警告しています。

ただし、最小限の変更で、ほぼすべてのデータベースエンジンで動作します。



問題の解決策ははるかにコンパクトであることが判明しました。MySQLは、「SELECT ... WHERE field LIKE 'pattern'」ではなく、高度な構造「SELECT ... WHERE field REGEXP 'regexp'」をサポートします。



合計-MySQLを使用する際のパフォーマンスが大幅に向上したコンパクトなコード

はるかに良い
 function r2e ($txt) { $txt=mb_strtolower($txt,"windows-1251"); $sr=array("","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""); $se=array("(x|[kc]s)","e[yi]","o(v|ff)","a","b","[vw]","g","d","e","[yj]o","z(h)*","[zs]","i","[jy]","[kc]","l","m","n","o","p","r","s","t","u","f","(k|c)*h","(c|ts)","ch","sh","s(h)*(c)*h","","y","","e","[yj]*u","[yj]a"); return str_replace($sr,$se,$txt); }
      
      







結果は次の形式の文字列です

 ochen prosta[yj]a fra[zs]a na russ[kc]om [yj]a[zs]y[kc]e
      
      





「SELECTカラムFROMテーブルWHERE searchField REGEXP '$ txt'」への挿入に非常に適しています。実際は、$ txtです。



他の一般的なDBMSはどうですか?

-残念ながら、MSSQLではすべてがそれほどバラ色ではありませんでした-CLRモジュールを使用して(たとえば、 ここから )、正規表現のサポートを取得できます。

-T-SQL(Oracle)ではすべて問題ありません。少なくとも10GバージョンではREGEXP_LIKE(fieldName、regexpString)があります。

-PostgreSQLにはかなり長い間、regexp_matches(fieldName、regexpString)がありました。

-FireBirdでSIMILAR TOを使用できます。たとえば、s(h)*(s)* hの代わりに見事にロシア語の「」の構文を作り直す必要があります。s(h){0,1} {0,1}として記述する必要がありますhそしてさらに類推によって。



All Articles