使用 NSScanner 查找字符串中的所有数字

find all numbers in a string with a NSScanner

我使用下面的代码从 inputString 中使用 NSScanner

提取数字
NSString *inputString = @"Dhoni7 notout at183*runs in 145andhehit15four's and10sixers100";
NSString *numberString;
NSArray *elements = [inputString componentsSeparatedByString:@" "];
for (int i=0; i<[elements count];i++)
{
    NSScanner *scanner = [NSScanner scannerWithString:[elements objectAtIndex:i]];
    NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:@"1234567890"];

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

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

    // Result.
    int number = [numberString integerValue];
    if (number != 0)
    {
        NSLog(@"%d\n",number);
        numberString = nil;
    }
}

我的预期输出是 7 183 145 15 10 100

但我得到的输出是 7 183 145 10

它只是从每个单词中提取第一次出现的数字。例如:如果它的 Dho7ni89 它只检测到 7 而没有检测到 89。如果有人能帮我想出解决这个问题的方法,我会很高兴。

你的错误很简单:你一开始就做出了错误的假设。你人为地将字符串分成单词:

NSArray *elements = [inputString componentsSeparatedByString:@" "];
for (int i=0; i<[elements count];i++) {
    // scan for one number
}

因此,这正是发生的事情。每个 word 被扫描为 one 号码,once。如果一个单词包含两个数字,则永远不会扫描第二个数字 - 因为这不是您所说的。

解决办法是停止做出错误的假设。根本不要将字符串分成单词!继续重复这个过程:

* scan up to a number
* scan the number

...直到到达扫描仪字符串的末尾 (isAtEnd)。

Matt 的速度稍快一些。 为什么要在开头拆分字符串?
稍微重新安排一下代码就会产生所需的结果:

NSScanner *scanner = [NSScanner scannerWithString:@"Dhoni7 notout at183*runs in 145andhehit15four's and10sixers100"];
NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:@"1234567890"];

while (true) {
    // Throw away characters before a number
    [scanner scanUpToCharactersFromSet:numbers intoString:NULL];

    // Read the number
    NSString *numberString;
    if ([scanner scanCharactersFromSet:numbers intoString:&numberString]) {
        long number = [numberString integerValue];
        NSLog(@"%ld\n",number);
    } else {
        break;
    }
}

正在输出

7 183 145 15 10 100

注意
您也可以使用

NSCharacterSet *numbers = [NSCharacterSet decimalDigitCharacterSet];

过滤掉数字。我发现这比列出字符要简洁一些。但是,它将包括例如印度文字和阿拉伯文字的十进制数字。