Come ricorda Tim, possiamo usare espressioni regolari per abbinare testo contenente i
o ı
. Inoltre non volevo aggiungere un nuovo campo o modificare i dati di origine mentre la ricerca cerca enormi quantità di stringa. Così ho trovato una soluzione usando le espressioni regolari e NSPredicate
.
Creare la categoria NSString
e copiare questo metodo. Restituisce il modello di corrispondenza or
di base. Puoi usarlo con qualsiasi metodo che accetta pattern di espressioni regolari.
- (NSString *)zst_regexForTurkishLettersWithCaseSensitive:(BOOL)caseSensitive
{
NSMutableString *filterWordRegex = [NSMutableString string];
for (NSUInteger i = 0; i < self.length; i++) {
NSString *letter = [self substringWithRange:NSMakeRange(i, 1)];
if (caseSensitive) {
if ([letter isEqualToString:@"ı"] || [letter isEqualToString:@"i"]) {
letter = @"[ıi]";
} else if ([letter isEqualToString:@"I"] || [letter isEqualToString:@"İ"]) {
letter = @"[Iİ]";
}
} else {
if ([letter isEqualToString:@"ı"] || [letter isEqualToString:@"i"] ||
[letter isEqualToString:@"I"] || [letter isEqualToString:@"İ"]) {
letter = @"[ıiIİ]";
}
}
[filterWordRegex appendString:letter];
}
return filterWordRegex;
}
Quindi, se il termine di ricerca è Şırnak
, esso crea Ş[ıi]rnak
per maiuscole e minuscole e Ş[ıiIİ]rnak
per caso ricerca maiuscole.
E qui ci sono i possibili usi.
NSString *testString = @"Şırnak";
// First create your search regular expression.
NSString *searchWord = @"şır";
NSString *searchPattern = [searchWord zst_regexForTurkishLettersWithCaseSensitive:NO];
// Then create your matching pattern.
NSString *pattern = searchPattern; // Direct match
// NSString *pattern = [NSString stringWithFormat:@".*%@.*", searchPattern]; // Contains
// NSString *pattern = [NSString stringWithFormat:@"\\b%@.*", searchPattern]; // Begins with
// NSPredicate
// c for case insensitive, d for diacritic insensitive
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self matches[cd] %@", pattern];
if ([predicate evaluateWithObject:testString]) {
// Matches
}
// If you want to filter an array of objects
NSArray *matchedCities = [allAirports filteredArrayUsingPredicate:
[NSPredicate predicateWithFormat:@"city matches[cd] %@", pattern]];
È inoltre possibile utilizzare NSRegularExpression
ma penso che con cassa e diacritic ricerca maiuscole con NSPredicate
è molto più semplice.
Non penso che sia valsa la pena di cercare attraverso la documentazione di Apple, vorrei solo usare un'espressione regolare al vostro posto. –
I documenti che menzioni riguardano una situazione diversa da quella che hai qui. Se si dispone di una stringa con il maiuscolo i senza maiuscole e si esegue una ricerca insensibile alle maiuscole e minuscole con una i regolare, funzionerà correttamente a meno che non si utilizzi la lingua turca. Con le impostazioni locali turche, il maiuscolo i senza maiuscole può essere trovato solo con un i senza punto minuscolo, non un normale io. Ho fatto alcuni test e, a prescindere dalle impostazioni locali, non sembra esserci alcun modo per trovare la corrispondenza con la i senza puntini con una i normale. Forse è un bug. – rmaddy
@rmaddy Ho appena pensato che se una ricerca insensibile al caso per 'I' corrisponde sia a' i' che a 'ı', allora _surely_ una ricerca insensibile al maiuscolo per' i' corrisponde sia a 'i' che a' ı'. Forse ho solo bisogno di sapere di più sulla lingua turca :( – deanWombourne