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

Man*_*sha 7 string objective-c nsnumber number-formatting 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的预期产量是7 183 145 15 10 100

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

它只是从每个单词中提取第一个出现的数字.例如:如果它的Dho7ni89它只检测到7并且没有检测到89.如果有人帮助我找到解决方法,我会很高兴.

luk*_*302 10

马特有点快.为什么你在开始时拆分你的字符串?
一点代码重新排列将产生所需的结果:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出

7 183 145 15 10 100

注意
您也可以使用

NSCharacterSet *numbers = [NSCharacterSet decimalDigitCharacterSet];
Run Code Online (Sandbox Code Playgroud)

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


mat*_*att 8

你的错误很简单:你已经开始做出错误的假设.你人为地将字符串分成单词:

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

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

解决方案是停止做出错误的假设.不要将字符串分成单词!只是不断重复这个过程:

* scan up to a number
* scan the number
Run Code Online (Sandbox Code Playgroud)

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

  • 当然,我实际上可以为你写出代码,但这不会给你带来任何挑战!我更喜欢_teach_你如何_think_关于问题,让_you_解决它.你已经拥有了所需的所有代码...... (3认同)