NSString: méthode facile pour enlever les accents UTF-8 d'une chaîne?

je veux changer une phrase, par exemple:

Être ou ne pas être. C était là-bas.

devient:

Etre ou ne pas etre. C'etait la-bas.

y a-t-il un moyen facile de faire cela avec NSString? Ou est-ce que je dois développer cela tout seul en vérifiant chaque char?

42
demandé sur Cœur 2012-06-07 17:06:02

8 réponses

NSString *str = @"Être ou ne pas être. C'était là-bas.";
NSData *data = [str dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *newStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(@"%@", newStr);

... ou essayez d'utiliser NSUTF8StringEncoding à la place.

Liste des types de codage ici:

https://developer.apple.com/documentation/foundation/nsstringencoding


FTR voici une ligne de chemin à écrire cette grande réponse:

yourString = [[NSString alloc]
  initWithData:
    [yourString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]
  encoding:NSASCIIStringEncoding];
55
répondu Luke 2017-07-02 03:00:15

Mattt Thompson a couvert ceci en NSHipster et encore WWDC 2013 session 228

TL;DR

NSMutableString *str = [@"Être ou ne pas être. C'était là-bas." mutableCopy];
CFStringTransform((__bridge CFMutableStringRef)string, NULL, kCFStringTransformStripCombiningMarks, NO);

devrait faire l'affaire, ça a bien marché pour moi.

Avertissement Comme beaucoup de gens dans les commentaires disent que cela devrait être la réponse acceptée, je tiens à faire une mise en garde pour cette méthode. Cette méthode est sacrément lente et devrait être utilisée avec soin si d'énormes quantités de chaîne / données doivent être transformées

48
répondu tapi 2016-05-12 08:00:43

Avez-vous essayé

[string stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]]

ou

Boolean CFStringTransform (
   CFMutableStringRef string,
   CFRange *range,
   CFStringRef transform,
   Boolean reverse
);

?

CFStringTransform& Transformer Les Identificateurs

NSMutableString *string = ...;
CFMutableStringRef stringRef = (__bridge CFMutableStringRef)string;
CFStringTransform(stringRef, NULL, kCFStringTransformToLatin, NO);
NSLog(@"%@", string);
22
répondu Regexident 2012-06-07 13:25:19

Juste une mise à jour pour dire que cela peut être fait comme ça dans swift:

"Être ou ne pas être. C'était là-bas.".stringByFoldingWithOptions(NSStringCompareOptions.DiacriticInsensitiveSearch, locale: NSLocale.currentLocale())

-- > "Etre ou ne pas être. C'etait la-bas."

15
répondu valR 2015-01-25 22:02:32
  • CFStringTransform (Task 1)
  • stringByFoldingWithOptions (Task 2)

La Tâche 2 est toujours plus rapide, par exemple:

Task 1 took 9.49736100435257 seconds.
Task 2 took 1.96649599075317 seconds.

Ici le test:

    let timer = ParkBenchTimer()
    for _ in 1...1000000 {
        let mStringRef = NSMutableString(string: "Être ou ne pas être. C'était là-bas.") as CFMutableStringRef
        CFStringTransform(mStringRef, nil, kCFStringTransformStripCombiningMarks, false)
        String(mStringRef)
    }
    print("Task 1 took \(timer.stop()) seconds.")

    let timer2 = ParkBenchTimer()
    for _ in 1...1000000 {
        "Être ou ne pas être. C'était là-bas.".stringByFoldingWithOptions(NSStringCompareOptions.DiacriticInsensitiveSearch, locale: NSLocale.currentLocale())
    }
    print("Task 2 took \(timer2.stop()) seconds.")

ParkBenchTimer par Klaas: https://stackoverflow.com/a/26578191/1097106

9
répondu svrs 2017-05-23 12:18:17

Swift 3 (testé dans l'aire de jeux)

//String+StripCombiningMarks.swift

extension String {
    /// strip combining marks (accents or diacritics)
    var stripCombiningMarks: String {
        let mStringRef = NSMutableString(string: self) as CFMutableString
        CFStringTransform(mStringRef, nil, kCFStringTransformStripCombiningMarks, false)
        return mStringRef as String
    }
}

Utilisation:

let umlaut = "äöüÄÖÜ" //ÄÖÜ
let stripped = umlaut.stripCombiningMarks //aouAOU
4
répondu Peter Kreinz 2017-04-13 11:23:45

voici le code complet. utilisez la fonction stringbyfoldignWithOptions.

NSString *str1=@"Être ou ne pas être C'était là-bas"; NSString *str2=[str1 stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale systemLocale]]; NSLog(@"%@",str2);

3
répondu Hitesh Agarwal 2016-06-23 07:02:27

Pour ceux qui veulent un Swift version de CFStringTransform solution:

let stripAccentAndDiacritics: (String) -> String = {
    var mStringRef = NSMutableString(string: ) as CFMutableStringRef
    CFStringTransform(mStringRef, nil, kCFStringTransformStripCombiningMarks, Boolean(0))
    return String(mStringRef)
}
1
répondu clmntcrl 2015-05-06 09:11:37