2017-12-05 17 views
0

だから私はユーザー提供の文字列で検索/フィルタリングする必要があるSTLベクトルを持っています。 (この特定のユースケースでそれを行う特定の/より良い方法がある場合は、これを言及してください)C++:アクセント付き文字を無視した検索

現在のところ、このコードを繰り返し実行することで、それは一致します。

しかし、私たちの問題はアクセント付きの文字に由来します。私たちの望むふるまいは、発音区別(diacritics)に関係なく文字列を一致させるための検索です(つまり、「テレフォノ」は「teléfono」にも一致します)。

理想的には、他のライブラリブーストよりも?

+0

[すべてのアクセント付き文字をC++の通常の文字に変更](https://stackoverflow.com/questions/14094621/change-all-accessed-letters-to-normal-letters-in-c) – Kevin

+0

I私の質問は本当に重複しているとは思わない。つまり、私はバックアップ計画としてそれをすることを考えましたが、実際にやっていることではありません。 –

+1

真の*複製ではないと思いますが、あなたのソリューションの一部として間違いなく使用することができます。 – Kevin

答えて

0

文字列のマッチングについて質問するときに文字エンコーディングが何であるかを知ることは役に立ちます。つまり、UTF-8などです。発音区別記号を扱うときのアプローチの1つは、文字列比較。一致のデータベースには発音区別記号が含まれておらず、比較する前に検索入力文字列を消毒します。

+0

私は上記のように、これは私の計画Bとなるでしょう。歌のリスト(アーティスト/タイトル)ですので、私は表示のために発音区別記号を保持したいと思います。私はおそらく、アーティストとタイトル(iTunesのようなもの)のサニタイズバージョンを表現するために、私たちの構造体のメンバーを2人追加することを考えましたが、可能ならばそのアプローチを避けたいと思います。 –

0

短い答え:両方の文字列を「正規化」し、検索/比較を行います。

Unicodeは複数のアクセント付き文字を複数表現しています。アクセントのある文字を表す単一のコードポイント(U + 00E9 LATIN SMALL EとACUTE ACCENT)がありますが、コードポイントの組み合わせで表すこともできます(U + 0065 LATIN SMALL LETTER EとU + 0301 COMBINING ACUTE ACCENT )。これに対処する一般的な方法は、1つのノーマルフォームC(事前に構成された文字の場合)またはD(構成されていない文字の場合)を選択することです。ノーマライズは、それよりも複雑に見えます。両方の文字列が同じ標準形式になったら、それらを直接比較することができます。

発音区別符を完全に無視する場合は、独自の正規化スキームを作成できます。たとえば、事前に作成された文字を分解してから、すべての合成コードポイントを削除することができます。アクセント付き文字が元々どのように表現されていたかにかかわらず、ベース文字がアクセント付き文字と一致することができます。

Unicode(KCおよびKD)には、ほとんどの特殊文字を最もよく似た基本文字に置き換える "kompatibility"標準形式もあります。発音区別弁の場合、私はこれが同じことをすると思います。だから、もしあなたがUnicodeライブラリを持っていれば、それを使って正規化のすべての苦労をすることができるかもしれません。

多くの場合、データベースはすでに通常の形式になっているため、検索文字列を正規化するだけです。

すべてが複雑すぎる場合、別の方法は、どの表現にも一致する正規表現を作成することです。たとえば、検索キーがtelefonoの場合は、t(e|\u00E9|e\u0301)l(e|\u00E9|e\u0301)f(o|\u00F3|o\u0301)n(o|\u00F3|o\u0301)のような正規表現に変換します。それらの正規表現は、マッチをどれだけ柔軟にしたいかによってかなり高速になる可能性があります。

+0

それは基本的に曲のリストであり、検索はユーザーの入力であるため、ほとんどの場合可能性があるので、_flexible_する必要があります。私はICUを使うことができたことを知りました。なぜなら、私たちのアプリの中の他のものは既にそれに依存しているからです。したがって、それ以上の依存関係は追加されません。私はそれを行う方法を把握する必要があります。 –

関連する問題