web-dev-qa-db-fra.com

Objective-C: Trouver des nombres dans une chaîne

J'ai une chaîne qui contient des mots ainsi qu'un nombre. Comment puis-je extraire ce nombre de la chaîne?

NSString *str = @"This is my string. #1234";

Je voudrais être capable de dépouiller 1234 comme un int. La chaîne aura des numéros et des mots différents à chaque fois que je la recherche.

Des idées?

37
Nic Hubbard

Voici une solution basée sur NSScanner :

// Input
NSString *originalString = @"This is my string. #1234";

// Intermediate
NSString *numberString;

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

// Throw away characters before the first number.
[scanner scanUpToCharactersFromSet:numbers intoString:NULL];

// Collect numbers.
[scanner scanCharactersFromSet:numbers intoString:&numberString];

// Result.
int number = [numberString integerValue];

(Certaines des nombreuses) hypothèses faites ici:

  • Les chiffres sont 0-9, pas de signe, pas de point décimal, pas de séparateur, etc. Vous pouvez ajouter des caractères de signe à NSCharacterSet si nécessaire.
  • Il n'y a pas de chiffres ailleurs dans la chaîne, ou s'ils existent après le nombre que vous souhaitez extraire.
  • Le nombre ne débordera pas int.

Sinon, vous pouvez numériser directement dans la variable int:

[scanner scanUpToCharactersFromSet:numbers intoString:NULL];
int number;
[scanner scanInt:&number];

Si le # marque le début du nombre dans la chaîne, vous pouvez le trouver au moyen de:

[scanner scanUpToString:@"#" intoString:NULL];
[scanner setScanLocation:[scanner scanLocation] + 1];
// Now scan for int as before.
100
martin clayton

Solution autonome:

+ (NSString *)extractNumberFromText:(NSString *)text
{
  NSCharacterSet *nonDigitCharacterSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
  return [[text componentsSeparatedByCharactersInSet:nonDigitCharacterSet] componentsJoinedByString:@""];
}

Traite les cas suivants:

  • @ "1234" → @ "1234"
  • @ "001234" → @ "001234" 
  • @ "le texte principal est supprimé 001234" → @ "001234"
  • @ "001234 le texte de fin est supprimé" → @ "001234"
  • @ "a0b0c1d2e3f4" → @ "001234"

J'espère que cela t'aides!

41
Zorayr

Vous pouvez utiliser la classe NSRegularExpression, disponible depuis iOS SDK 4.

Ci-dessous un code simple pour extraire les nombres entiers ( "\ d +" motif regex):

- (NSArray*) getIntNumbersFromString: (NSString*) string {

  NSMutableArray* numberArray = [NSMutableArray new];

  NSString* regexPattern = @"\\d+";
  NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:regexPattern options:0 error:nil];

  NSArray* matches = [regex matchesInString:string options:0 range:NSMakeRange(0, string.length)];
  for( NSTextCheckingResult* match in matches) {
      NSString* strNumber = [string substringWithRange:match.range];
      [numberArray addObject:[NSNumber numberWithInt:strNumber.intValue]];
  }

  return numberArray; 
}
3
Farlei Heinen

Essayez cette réponse de Stack Overflow pour un joli morceau de code C qui fera l'affaire:

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

De loin la meilleure solution! Je pense que regexp serait mieux, mais je suis un peu suxif ;-) cela filtre TOUS les nombres et les concats ensemble, créant une nouvelle chaîne. Si vous voulez diviser plusieurs numéros, changez-le un peu. Et rappelez-vous que lorsque vous utilisez ceci dans une grande boucle, cela coûte de la performance! 

    NSString *str= @"bla bla bla #123 bla bla 789";
    NSMutableString *newStr = [[NSMutableString alloc] init];;
    int j = [str length];
    for (int i=0; i<j; i++) {       
        if ([str characterAtIndex:i] >=48 && [str characterAtIndex:i] <=59) {
            [newStr appendFormat:@"%c",[str characterAtIndex:i]];
        }               
    }

    NSLog(@"%@  as int:%i", newStr, [newStr intValue]);
1
Roger

NSPredicate est la classe Cocoa permettant d'analyser la chaîne à l'aide de ICU expression régulière .

0
Daniel Farrell

Extension rapide pour obtenir le numéro d'une chaîne

extension NSString {

func getNumFromString() -> String? {

    var numberString: NSString?
    let thisScanner = NSScanner(string: self as String)
    let numbers = NSCharacterSet(charactersInString: "0123456789")
    thisScanner.scanUpToCharactersFromSet(numbers, intoString: nil)
    thisScanner.scanCharactersFromSet(numbers, intoString: &numberString)
    return numberString as? String;
}
}
0
Bhavesh Patel