Recherche dans une NSString et caractères spéciaux
Bonjour,
je fais une recherche dans une string.
Pour l'instant mon code est :
NSStringCompareOptions options = NSCaseInsensitiveSearch |
NSDiacriticInsensitiveSearch |
NSWidthInsensitiveSearch ;
NSString * name = @Très facile ? ;
NSRange range = NSMakeRange(0, name.length) ;
NSRange result = [name rangeOfString:stringToSearch
options:options
range:range
locale:[[NSLocale alloc] initWithLocaleIdentifier:@fr]]
return result.location != NSNotFound ;
Le problème est que si je recherche "facilé", il me retourne YES.
Je voudrais qu'il me retourne YES si je recherche "Tres" mais NO si je recherche "facilé".
Avez-vous déjà essayé de faire cela ?
Merci !
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
j'ai testé par curiosité, cela fonctionne... je te conseille de faire afficher la variable que tu testes dans un lot pour voir si est à la bonne valeur.
Je ne sais pas si c'est possible en une seule étape.
Une solution en deux étapes consisteraient à garder le test que tu fais deja et à ajouter un test avec une expression régulière.
En prenant le texte trouvé et en remplaçant toutes les lettres avec diacritic par un OU entre la lettre avec diacritic et son équivalent sans diacritic :
Par exemple si tu as trouvé Très avec Tres, tu vérifies si Tr[èe]s matche Tres.
Du coup facile ne matchera pas facilé.
ou compliqu[ée] ne matchera pas complà®que mais matchera complique
Après quelques essais, il s'avère que transformer Très en Tr[èe]s n'est pas si simple.
Quelques indices :
-utiliser [[NSCharacterSet decomposableCharacterSet] characterIsMember]] pour trouver les caractères "spéciaux".
-utiliser [NSString rangeOfComposedCharacterSequenceAtIndex] pour extraire le caractère décomposable du NSString.
-utiliser CFStringTransform pour transformer 'è' en 'e'.
@denis : oui tu as raison. Avec le nouveau code, ça ne devrait pas marcher !
@FKDEV : merci pour ces pistes !
En gros, tu convertis ton "Très facile" en "Tres facile", puis tu cherches dedans le texte "Tres" (qu'il va trouver) ou "facilé" (qu'il ne va pas trouver).
Pour enlever les accents de ta chaà®ne, tu as la méthode "stringByFoldingWithOptions:locale:" de NSString, à laquelle il suffit de passer l'option "NSDiacriticInsensitiveSearch", et basta.
Putain, j'viens d'apprends que toutes ces p'tites merdes avaient un nom : diacritique. J'ai été obligé de googler/wikipédier ça
Intéressant en tout cas.
@Ali : je pense que ta solution bugue : si je recherche "Très", il ne va pas trouver !
Il faut d'abord chercher le texte dans la chaà®ne d'origine avec accents et ne chercher dans la chaà®ne où on a retiré les accents que si on a pas trouvé avant
Ali, je crois que ça ne fonctionnera pas avec un mot où on aurait oublié un accent comme "apprecié" au lieu de "apprécié".
Voici une méthode qui marche.
C'est une catégorie sur NSString.
@Ali et FKDEV : merci pour votre aide !
En fait la règle n'est pas claire, où est-ce qu'il veut bien que ça trouve et dans quel cas faut-il que ça ne trouve pas ?
Parce que si tu regardes l'exemple "facilé" / facile on pourrait penser que ça rentre dans le même cas que "apprécié" / "apprecié" non ?
@FKDEV : oui, tu as raison !
@Ali : la règle c'est que si j'oublie un accent ça matche, si je mets un accent en trop, ça ne matche pas.
Du coup, peut-être qu'il faut tester caractère par caractère...
Je m'en suis sorti avec une méthode astucieuse !
En effet, si on compare les NSString, alors @é ≥ @e.
Je fais donc comme suit : je teste d'abord sans les accents.
Je récupère la sous-string qui matche.
Puis, je compare (au sens ≤) string cherchée avec celle trouvée.
PS : il va encore rester quelques bugs quand même...
Par exemple, "Prè" matche "Pré"
Et si tu mets du multi-diacritiques, un peu dans tous les sens, genre un O avec accent aigu + un accent rond (à la suédoise) et que tu le compares avec un 0 avec cédille et barré (à la norvégienne) ?
Ali, ma solution marche dans tout ces cas là .
Mais je trouve quand meme que la solution trouvée par colas est maligne.
J'ai finalement implémenté la solution de FKDEV :
Les méthodes auxiliaires :
1) une méthode qui décompose une string en array de strings de taille 1
2) une méthode qui crée l'expression régulière
C'est pas trop lent ?
Sur mon mac book pro, pas de problème, ça tourne !