2013-01-03 19 views
9

Sto cercando di interrogare un database delle denominazioni dei vini, molti dei quali contengono accenti (ma non in modo uniforme, e quindi vini simili possono essere immesse con o senza accenti)MySQL REGEXP interrogazione - accento ricerca maiuscole

la query di base assomiglia a questo:

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

che restituirà le voci con 'Faugères' nel titolo, ma non '' Faugeres

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

fa il contrario. qualcosa

avevo pensato come:

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

potrebbe fare il trucco, ma questo restituisce solo i risultati senza gli accenti.

Il campo è fascicolato come utf8_unicode_ci, che da quello che ho letto è come dovrebbe essere.

Qualche suggerimento ?!

+0

Ho avuto lo stesso problema. Guarda il mio argomento qui: http://stackoverflow.com/questions/33722136/how-to-search-string-using-entity-framework-with-contains-and-with-accent-insen/34047990#34047990 – Dan

risposta

4

You're out of luck:

Attenzione

Il lavoro degli operatori RegExp e RLIKE nella moda di byte-saggio, in modo che siano non multi-byte sicuro e possono produrre risultati inaspettati con multi-byte set di caratteri. Inoltre, questi operatori confrontano i caratteri di i loro valori di byte e i caratteri accentati potrebbero non essere uguali a anche se un dato confronto li considera uguali.

I [[:<:]] e [[:>:]] operatori espressioni regolari sono marcatori per confini di parola. Il più vicino si può ottenere con l'operatore LIKE è qualcosa su questa linea:

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

Come si può vedere che non è del tutto equivalente perché ho ristretto la nozione di confine di parola in spazi. Aggiungere più clausole per altri confini sarebbe un disastro.

È anche possibile utilizzare ricerche di testo completo (sebbene non sia la stessa) ma non è possibile definire indici di testo completo nelle tabelle InnoDB (ancora).

Sei certamente fuori di fortuna :)

+0

Ouch. .. - OK, quindi se passo a: DOVE 'wine_name' LIKE '% Faugeres%' c'è qualche aspetto negativo? Non riesco a ricordare il motivo per cui stavamo usando REGEXP per cominciare, ma penso che riguardasse la ricerca di parole intere e non di stringhe all'interno di parole, che la dichiarazione simile avrebbe fatto ... – freestate

+0

Questa soluzione potrebbe non essere così buona perché non funzionerà se la parola ha altri personaggi dopo o prima, come:'Faugères.''Faugères! ''Faugères?' '(Faugères' e molte altre varianti. Sto cercando il samething: REGEXP per utilizzare i limiti delle parole ma senza accento. – steps

1

utf8_general_ci vedere alcuna differenza tra accento/senza accento durante l'ordinamento. Forse è vero anche per le ricerche. Inoltre, modificare REGEXP in LIKE. REGEXP effettua il confronto binario.

0

Ok, mi sono imbattuto in questa domanda mentre cercavo qualcos'altro.

Questo restituisce true.

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

Spero che sia d'aiuto.

Aggiunta del '+' Indica l'espressione regolare per cercare una o più occorrenze dei caratteri.

0

Per risolvere questo problema, ho provato diverse cose, incluso l'utilizzo della parola chiave binaria o del set di caratteri latin1, ma senza risultato.
Infine, considerando che si tratta di un bug MySql, ho finito per sostituire le E ed E caratteri,

Ti piace questa:

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

Perché REGEXP e RLIKE sono byte orientati, hai provato:

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

Questo dice che uno di questi deve essere nell'espressione. Si noti che non ho usato il segno più (+) perché ciò significa UNO O PIÙ. Dal momento che ne vuoi solo uno non dovresti usare il plus.

0

Ho avuto lo stesso problema cercando di trovare ogni record corrispondente a uno dei seguenti modelli: "copropriété", "copropriete", "COPROPRIÉTÉ", "Copropri? T?"

REGEXP 'copropri.{1,2}t.{1,2} ha funzionato per me. Fondamentalmente, .{1,2} dovrebbe funzionare in ogni caso se il carattere è codificato a 1 o 2 byte.

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

Attenzione
Il REGEXP e gli operatori RLIKE lavorare nella moda di byte-saggio, quindi non sono multibyte sicuri e possono produrre risultati imprevisti con i set di caratteri multibyte. Inoltre, questi operatori confrontano i caratteri in base ai loro valori di byte e i caratteri accentati potrebbero non essere paragonati come uguali anche se un dato confronto li considera come uguali.

Problemi correlati