【问题标题】:Objective-C: Find numbers in stringObjective-C:在字符串中查找数字
【发布时间】:2023-03-25 10:37:01
【问题描述】:

我有一个包含单词和数字的字符串。如何从字符串中提取该数字?

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

我希望能够将 1234 剥离为 int。每次搜索时,字符串都会有不同的数字和单词。

想法?

【问题讨论】:

标签: iphone objective-c ios nsstring nsnumber


【解决方案1】:

这是一个基于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];

(其中一些)在这里做出的假设:

  • 数字是 0-9,没有符号,没有小数点,没有千位分隔符等。如果需要,您可以将符号字符添加到 NSCharacterSet。
  • 字符串中的其他地方没有数字,或者如果有,它们在您要提取的数字之后
  • 号码不会溢出int

您也可以直接扫描到int

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

如果# 标记了字符串中数字的开头,您可以通过以下方式找到它:

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

【讨论】:

  • 很好的解决方案,这正是我所需要的!
  • 太棒了。很好的解决方案。谢谢。
  • 如果我在字符串的不同位置有多个数字,那么它只返回第一个数字
【解决方案2】:

独立解决方案:

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

处理以下情况:

  • @"1234" → @"1234"
  • @"001234" → @"001234"
  • @"前导文本被删除 001234" → @"001234"
  • @"001234 尾随文本被删除" → @"001234"
  • @"a0b0c1d2e3f4" → @"001234"

希望这会有所帮助!

【讨论】:

  • 这是这篇文章中最好和体面的答案。这比接受的答案要好。
  • 是否也可以去掉前导零?
【解决方案3】:

您可以使用自 iOS SDK 4 起可用的 NSRegularExpression 类。

下面是一个提取整数的简单代码("\d+" 正则表达式模式):

- (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; 
}

【讨论】:

  • 正则表达式很强大。但在这个简单的情况下,我认为@Zorayr 的答案是最好的。
  • 不管我的回答如何,我认为在这里使用正则表达式可能有点矫枉过正,而且还有更多的维护危险;没有人真正了解正则表达式,而且很难调试。
  • @Zorayr :我同意这可能有点矫枉过正,但我​​认为这不会造成维护隐患。实际上,添加新功能真的很容易,开发人员可以在任何接受正则表达式的语言中重用该模式。
  • 我添加一个例子让我的答案更清楚。它适用于整数值。要扩展为浮点值,请使用以下模式:@"[\\d[.]]+"
  • 非常好。不要害怕正则表达式。
【解决方案4】:

试试 Stack Overflow 中的 this answer 以获得一段不错的 C 代码,它可以解决问题:

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

【讨论】:

  • 我不建议在这里使用 c 风格的 for 循环;这可能会导致较大的字符串出现明显延迟,尤其是在主线程上执行时。
【解决方案5】:

迄今为止最好的解决方案!我认为 regexp 会更好,但我有点 sux ;-) 这会过滤所有数字并将它们连接在一起,形成一个新字符串。如果要拆分多个数字,请稍微更改一下。请记住,当您在一个大循环中使用它时,它会降低性能!

    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]);

【讨论】:

    【解决方案6】:

    用于从字符串中获取数字的 Swift 扩展

    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;
    }
    }
    

    【讨论】:

      【解决方案7】:

      NSPredicate 是使用ICU regular expression 解析字符串的Cocoa 类。

      【讨论】:

      • NSPredicate 正则表达式匹配在 iOS SDK 上不起作用。
      • 哦。谢谢,我不知道(我大部分时间都在 MacOS 世界中度过)。
      • NSPredicate 自 iOS 3.0 以来一直是 iOS SDK 的一部分。
      猜你喜欢
      • 1970-01-01
      • 2011-12-13
      • 1970-01-01
      • 2012-10-17
      • 2012-03-20
      • 2019-02-01
      • 1970-01-01
      • 2012-11-10
      • 1970-01-01
      相关资源
      最近更新 更多