158 votes

Supprime tout sauf les chiffres de NSString

J'ai une chaîne NSString (numéro de téléphone) avec des parenthèses et des tirets, car certains numéros de téléphone sont formatés. Comment supprimer de la chaîne tous les caractères sauf les chiffres ?

377voto

simonobo Points 1557

Vieille question, mais que diriez-vous de :

  NSString *newString = [[origString componentsSeparatedByCharactersInSet:
                [[NSCharacterSet decimalDigitCharacterSet] invertedSet]] 
                componentsJoinedByString:@""];

Il explose la chaîne source sur l'ensemble des non-chiffres, puis les réassemble en utilisant un séparateur de chaîne vide. Cette méthode n'est pas aussi efficace que la sélection des caractères, mais elle est beaucoup plus compacte en termes de code.

6 votes

Merci ! Pour les autres débutants, vous pouvez créer votre propre NSCharacterSet personnalisé en faisant NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:@"charactersGoHere"]

1 votes

Merci beaucoup ! Juste par curiosité, avez-vous une idée de la raison pour laquelle NSString *pureNumbers = [pureNumbers stringByTrimmingCharactersInSet: [NSCharacterSet decimalDigitCharacterSet] invertedSet] Ne fonctionne pas ?

1 votes

@Tommecpe stringByTrimmingCharactersInSet ne supprime que le début et la fin de la chaîne, donc il n'affecte pas après le premier caractère non correspondant, ou avant le dernier caractère non correspondant.

76voto

Nathan de Vries Points 10895

Il n'est pas nécessaire d'utiliser une bibliothèque d'expressions régulières comme le suggèrent les autres réponses -- la classe que vous recherchez s'appelle NSScanner . Il est utilisé comme suit :

NSString *originalString = @"(123) 123123 abc";
NSMutableString *strippedString = [NSMutableString 
        stringWithCapacity:originalString.length];

NSScanner *scanner = [NSScanner scannerWithString:originalString];
NSCharacterSet *numbers = [NSCharacterSet 
        characterSetWithCharactersInString:@"0123456789"];

while ([scanner isAtEnd] == NO) {
  NSString *buffer;
  if ([scanner scanCharactersFromSet:numbers intoString:&buffer]) {
    [strippedString appendString:buffer];

  } else {
    [scanner setScanLocation:([scanner scanLocation] + 1)];
  }
}

NSLog(@"%@", strippedString); // "123123123"

EDIT : J'ai mis à jour le code parce que l'original a été écrit à partir de ma tête et j'ai pensé qu'il serait suffisant pour indiquer aux gens la bonne direction. Il semble que les gens recherchent un code qu'ils peuvent simplement copier-coller directement dans leur application.

Je suis également d'accord que la solution de Michael Pelz-Sherman est plus appropriée que d'utiliser NSScanner donc vous pourriez vouloir y jeter un coup d'oeil.

0 votes

+1 Bonne réponse qui répond directement à la question. J'ai modifié ma réponse pour préconiser cette approche, mais je laisse la deuxième moitié telle quelle, car elle est toujours utile) qui aborde le problème inverse du formatage d'un numéro de téléphone pour l'affichage. (Ensuite, pouvez-vous laisser un commentaire constructif lors du downvoting, ne serait-ce que pour les lecteurs ultérieurs) ?

4 votes

Il peut être utile de savoir qu'il existe une méthode +decimalDigitCharacterSet de NSCharacterSet qui vous donnera tous les chiffres décimaux. Cet ensemble est légèrement différent de celui que Nathan énumère, car il comprend tous les symboles qui représentent les chiffres décimaux, y compris, par exemple, les chiffres arabo-indiques ( etc). En fonction de votre application, cela peut occasionnellement poser problème, mais en général, c'est bon ou neutre, et un peu plus court à taper.

0 votes

Je suis pratiquement sûr que cette réponse ne fonctionne pas et qu'elle n'est pas vraiment la bonne approche du problème. Si vous essayez réellement le code tel qu'il est présenté (en ajoutant d'abord un @ avant le premier paramètre de NSLog, pour en faire une chaîne de caractères objc), vous constaterez qu'il affiche <null> ou se plante. Pourquoi ? Voir ma réponse ci-dessous.

63voto

Yacine Filali Points 808

La réponse acceptée est exagérée par rapport à ce qui est demandé. C'est beaucoup plus simple :

NSString *pureNumbers = [[phoneNumberString componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];

3 votes

La réponse (actuellement) acceptée est plus ou moins identique à celle-ci, mais a été postée 13 mois plus tôt.

0 votes

Au moment où j'ai répondu à cette question, il n'y avait pas cette réponse. Il semble toutefois que la réponse actuelle ait déjà été proposée et que je l'aie manquée : web.archive.org/web/20101115214033/http://stackoverflow.com/

30voto

C'est génial, mais le code ne fonctionne pas pour moi sur le SDK de l'iPhone 3.0.

Si je définis strippedString comme vous le montrez ici, j'obtiens une BAD ACCESS error lorsqu'on essaie de l'imprimer après le scanCharactersFromSet:intoString appeler.

Si je le fais comme ça :

NSMutableString *strippedString = [NSMutableString stringWithCapacity:10];

Je me retrouve avec une chaîne vide, mais le code ne se plante pas.

J'ai dû recourir au bon vieux C à la place :

for (int i=0; i<[phoneNumber length]; i++) {
    if (isdigit([phoneNumber characterAtIndex:i])) {
        [strippedString appendFormat:@"%c",[phoneNumber characterAtIndex:i]];
    }
}

0 votes

J'utilise la version 3.0 et cela fonctionne pour moi. La réponse plus populaire de Vries n'a pas fonctionné.

0 votes

La réponse numéro un ne fonctionne pas pour moi. Le scanner s'arrête lorsqu'il atteint un ( ) ou - Cette réponse fonctionne très bien ! Le bon vieux C ! Merci.

2 votes

Notez seulement que le caractère '+' doit être autorisé pour le numéro de téléphone.

27voto

alex Points 1525

Bien qu'il s'agisse d'une vieille question avec des réponses fonctionnelles, j'ai manqué support des formats internationaux . D'après la solution de simonobo, le jeu de caractères modifié comprend un signe plus "+". Les numéros de téléphone internationaux sont également pris en charge par cette modification.

NSString *condensedPhoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:
              [[NSCharacterSet characterSetWithCharactersInString:@"+0123456789"]
              invertedSet]] 
              componentsJoinedByString:@""];

Les expressions Swift sont

var phoneNumber = " +1 (234) 567-1000 "
var allowedCharactersSet = NSMutableCharacterSet.decimalDigitCharacterSet()
allowedCharactersSet.addCharactersInString("+")
var condensedPhoneNumber = phoneNumber.componentsSeparatedByCharactersInSet(allowedCharactersSet.invertedSet).joinWithSeparator("")

Ce qui donne +12345671000 comme format commun de numéro de téléphone international.

2 votes

C'est la meilleure solution de la liste, surtout si vous avez besoin du signe plus pour les numéros de téléphone internationaux.

0 votes

Pour une raison quelconque, l'utilisation d'un jeu de caractères inversé me fait peur en termes de performances. Quelqu'un sait-il si cette crainte est infondée ?

0 votes

Celui-là a marché ! Pouvez-vous expliquer son fonctionnement ? @alex

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X