2013-01-03 5 views
9

多くのものにアクセントが含まれていますが(ユニフォームではないので、アクセントの有無にかかわらず同様のワインを入力することができます)MySQL REGEXPクエリ - アクセントを区別しない検索

基本的なクエリは次のようになります。タイトルに「Faugères」でのエントリを返します

SELECT * FROM `table` WHERE `wine_name` REGEXP '[[:<:]]Faugères[[:>:]]' 

ではなく、「Faugeres」

SELECT * FROM `table` WHERE `wine_name` REGEXP '[[:<:]]Faugeres[[:>:]]' 

は反対のことを行います。私が思っていた

のようなもの:

SELECT * 
FROM `table` 
WHERE `wine_name` REGEXP '[[:<:]]Faug[eèêéë]r[eèêéë]s[[:>:]]' 

は、トリックを行うかもしれないが、これが唯一のアクセントなしで結果を返します。

このフィールドは、utf8_unicode_ciとして照合されます。これは、私が読んだところから、どのようにするべきかです。

何か提案がありますか?

+0

私は同じ問題を抱えていました。ここのトピックを見てください:http://stackoverflow.com/questions/33722136/how-to-search-string-using-entity-framework-with-contains-and-with-accent-insen/34047990#34047990 – Dan

答えて

4

You're out of luck

警告

バイト単位方式でREGEXPとRLIKEオペレーターの仕事なので、彼らが ないマルチバイトでも安全であり、マルチバイト で予期しない結果が発生する可能性があり文字セットさらに、これらの演算子は、 の文字とそのバイト値を比較し、アクセント付きの文字は、指定された照合でそれらを等しく扱っても、 とは比較できません。

[[:<:]][[:>:]]正規表現演算子は、単語境界のマーカーです。あなたは私がスペースにワード境界の概念を制限してきたので、それは完全に同等ではありません見ることができるように

SELECT * 
FROM `table` 
WHERE wine_name = 'Faugères' 
    OR wine_name LIKE 'Faugères %' 
    OR wine_name LIKE '% Faugères' 

:あなたはLIKE演算子で達成することができ、最も近いが、このライン上のものです。他の境界のために句を追加することは混乱につながります。

フルテキスト検索を使用することもできます(同じではありません)が、InnoDBテーブルでフルテキストインデックスを定義することはできません(まだ)。

あなたは運が悪い確かだ:)

+0

おっと。 .. - OK、そうすれば、私は: WHERE 'wine_name' LIKE '%Faugeres%' のいずれかの欠点がありますか?なぜ私たちはREGEXPを使って始めているのか覚えていませんが、単語の中の文字列ではなく、単語全体を検索することにあったと思います。 – freestate

+0

この解決法はあまり良くないかもしれません'Faegères!''Faugères! ''Faugères?' '(Faugèresと他の多くのバリエーション) 私は何かを探しています:単語境界を使用するが、アクセントを区別しないREGEXP。 – steps

1

アクセント/並べ替えなしのアクセントとの間に有意差は見られないutf8_general_ci。おそらくこれも検索にも当てはまります。 また、REGEXPをLIKEに変更します。 REGEXPはバイナリ比較を行います。何か他のものを探しながら

0

[OK]を私はちょうどこの質問につまずきました。

これはtrueを返します。

SELECT 'Faugères' REGEXP 'Faug[eèêéë]+r[eèêéë]+s'; 

希望します。

'+'を追加するregexpに文字の1つ以上の出現を検索させます。

0

この問題を解決するために、バイナリキーワードやlatin1文字セットを使用するなど、さまざまなことを試しましたが、役に立たないものです。
最後に、それは、MySQLのバグであることを考えると、私はEとè文字を置き換えることになった、このよう

SELECT * 
FROM `table` 
WHERE replace(replace(wine_name, 'é', 'e'), 'è', 'e') REGEXP '[[:<:]]Faugeres[[:>:]]' 
3

REGEXPとRLIKEはバイト指向であるため、あなたは試してみました:

SELECT 'Faugères' REGEXP 'Faug(e|è|ê|é|ë)r(e|è|ê|é|ë)s'; 

これは、これらのうちの1つが式に含まれている必要があることを示しています。 1つ以上の意味でプラス(+)を使用していないことに注意してください。あなたは1つしか必要としないので、プラスを使用しないでください。

0

「copropriété」、「copropriete」、「COPROPRIÉTÉ」、「Copropri?t?」のいずれかのパターンに一致するすべてのレコードを検索しようとして同じ問題がありました。

REGEXP 'copropri.{1,2}t.{1,2}私のために働いた。 基本的には、.{1,2}は、文字が1または2バイトエンコードされているすべての場合に有効です。

説明:https://dev.mysql.com/doc/refman/5.7/en/regexp.html

警告
REGEXPとRLIKE演算子バイト単位方式での作業なので、彼らは安全なマルチバイトされていないと、マルチバイト文字セットと、予期しない結果が生じることがあります。さらに、これらの演算子は、文字をバイト値で比較し、指定された照合でそれらを等しく扱っても、アクセント付き文字は等しいとは比較できません。