web-dev-qa-db-fra.com

Supprimer les caractères non alphanumériques d'un NSString

Je recherche un moyen rapide et facile de supprimer les caractères non alphanumériques d'un NSString. Probablement quelque chose utilisant un NSCharacterSet, mais je suis fatigué et rien ne semble retourner une chaîne contenant uniquement les caractères alphanumériques d'une chaîne.

67
Jeff Kelley

Nous pouvons le faire en scindant puis en rejoignant. Nécessite OS X 10.5+ pour les composantsSeparatedByCharactersInSet:

NSCharacterSet *charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
NSString *strippedReplacement = [[someString componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@""];
143
user102008

Dans Swift, la componentsJoinedByString est remplacée par join(...); elle remplace donc ici les caractères non alphanumériques par un espace.

let charactersToRemove = NSCharacterSet.alphanumericCharacterSet().invertedSet
let strippedReplacement = " ".join(someString.componentsSeparatedByCharactersInSet(charactersToRemove))

Pour Swift2 ...

var enteredByUser = field.text .. or whatever

let unsafeChars = NSCharacterSet.alphanumericCharacterSet().invertedSet

enteredByUser = enteredByUser
         .componentsSeparatedByCharactersInSet(unsafeChars)
         .joinWithSeparator("")

Si vous souhaitez supprimer un seul caractère, par exemple, supprimez tous les retours ...

 enteredByUser = enteredByUser
         .componentsSeparatedByString("\n")
         .joinWithSeparator("")
21
Amro Shafie

En fin de compte, j'ai créé un NSCharacterSet et la méthode -invertedSet que j'ai trouvé (c'est étonnant de constater ce qu'une heure de sommeil supplémentaire permet d'obtenir des capacités de lecture de documentation). Voici l'extrait de code, en supposant que someString est la chaîne à partir de laquelle vous souhaitez supprimer les caractères non alphanumériques:

NSCharacterSet *charactersToRemove =
[[ NSCharacterSet alphanumericCharacterSet ] invertedSet ];

NSString *trimmedReplacement =
[ someString stringByTrimmingCharactersInSet:charactersToRemove ];

trimmedReplacement contiendra alors les caractères alphanumériques de someString.

19
Jeff Kelley

Swift 3 version de réponse acceptée:

let unsafeChars = CharacterSet.alphanumerics.inverted
let myStrippedString = myString.components(separatedBy: unsafeChars).joined(separator: "")
6
Travis M.

Une catégorie de nettoyage

J'ai un appel de méthode stringByStrippingCharactersInSet: et stringByCollapsingWhitespace qui pourrait être pratique de simplement se déplacer.

@implementation NSString (Cleanup)

- (NSString *)clp_stringByStrippingCharactersInSet:(NSCharacterSet *)set
{
    return [[self componentsSeparatedByCharactersInSet:set] componentsJoinedByString:@""];
}

- (NSString *)clp_stringByCollapsingWhitespace
{
    NSArray *components = [self componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    components = [components filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self <> ''"]];

    return [components componentsJoinedByString:@" "];
}

@end
1

Voici une version rapide de de la catégorie Cameron en tant qu’extension:

extension String {

    func stringByStrippingCharactersInSet(set:NSCharacterSet) -> String
    {
        return (self.componentsSeparatedByCharactersInSet(set) as NSArray).componentsJoinedByString("")
    }

    func stringByCollapsingWhitespace() -> String
    {
        var components:NSArray = self.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
        let predicate = NSPredicate(format: "self <> ''", argumentArray: nil)
        components = components.filteredArrayUsingPredicate(predicate)

        return components.componentsJoinedByString(" ")
    }
}
0
Aral Balkan

C'est un moyen plus efficace que la réponse fournie

+ (NSString *)alphanumericString:(NSString *)s {

    NSCharacterSet * charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
    NSMutableString * ms = [NSMutableString stringWithCapacity:[s length]];
    for (NSInteger i = 0; i < s.length; ++i) {
        unichar c = [s characterAtIndex:i];
        if (![charactersToRemove characterIsMember:c]) {
            [ms appendFormat:@"%c", c];
        }
    }
    return ms;

}

ou en tant que catégorie

@implementation NSString (Alphanumeric)

- (NSString *)alphanumericString {

    NSCharacterSet * charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
    NSMutableString * ms = [NSMutableString stringWithCapacity:[self length]];
    for (NSInteger i = 0; i < self.length; ++i) {
        unichar c = [self characterAtIndex:i];
        if (![charactersToRemove characterIsMember:c]) {
            [ms appendFormat:@"%c", c];
        }
    }
    return ms;

}

@end
0
Peter Lapisu

Le cycle normal serait le temps d'exécution plus rapide, je pense:

@implementation NSString(MyUtil)

- (NSString*) stripNonNumbers {
    NSMutableString* res = [NSMutableString new];
    //NSCharacterSet *numericSet = [NSCharacterSet decimalDigitCharacterSet];
    for ( int i=0; i < self.length; ++i ) {
        unichar c = [self characterAtIndex:i];
        if ( c >= '0' && c <= '9' ) // this looks cleaner, but a bit slower: [numericSet characterIsMember:c])
            [res appendFormat:@"%c", c];
    }
    return res;
}

@end
0
Dmitrym