objective-c 从 NSString 中删除除数字以外的所有内容

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1129521/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:54:55  来源:igfitidea点击:

Remove all but numbers from NSString

objective-cnsstring

提问by Ben Harris

I have an NSString (phone number) with some parenthesis and hyphens as some phone numbers are formatted. How would I remove all characters except numbers from the string?

我有一个带有括号和连字符的 NSString(电话号码),因为某些电话号码已格式化。如何从字符串中删除除数字以外的所有字符?

回答by simonobo

Old question, but how about:

老问题,但怎么样:

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

It explodes the source string on the set of non-digits, then reassembles them using an empty string separator. Not as efficient as picking through characters, but much more compact in code.

它在一组非数字上分解源字符串,然后使用空字符串分隔符重新组合它们。不如通过字符挑选那样有效,但代码更紧凑。

回答by Nathan de Vries

There's no need to use a regular expressions library as the other answers suggest -- the class you're after is called NSScanner. It's used as follows:

没有必要像其他答案所暗示的那样使用正则表达式库——你所追求的类被称为NSScanner。它的用法如下:

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:I've updated the code because the original was written off the top of my head and I figured it would be enough to point the people in the right direction. It seems that people are after code they can just copy-paste straight into their application.

编辑:我已经更新了代码,因为原始代码是从我的头顶上写下来的,我认为这足以将人们指向正确的方向。似乎人们追求代码,他们可以直接复制粘贴到他们的应用程序中。

I also agree that Michael Pelz-Sherman's solution is more appropriate than using NSScanner, so you might want to take a look at that.

我也同意 Michael Pelz-Sherman 的解决方案比 using 更合适NSScanner,所以你可能想看看。

回答by Yacine Filali

The accepted answer is overkill for what is being asked. This is much simpler:

接受的答案对于所问的问题来说太过分了。这要简单得多:

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

回答by Michael Pelz-Sherman

This is great, but the code does not work for me on the iPhone 3.0 SDK.

这很棒,但代码在 iPhone 3.0 SDK 上对我不起作用。

If I define strippedString as you show here, I get a BAD ACCESS errorwhen trying to print it after the scanCharactersFromSet:intoStringcall.

如果我像您在此处显示的那样定义了 strippedString,BAD ACCESS error则在scanCharactersFromSet:intoString调用后尝试打印它时会得到一个。

If I do it like so:

如果我这样做:

NSMutableString *strippedString = [NSMutableString stringWithCapacity:10];

I end up with an empty string, but the code doesn't crash.

我最终得到一个空字符串,但代码没有崩溃。

I had to resort to good old C instead:

我不得不求助于古老的C:

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

回答by alex

Though this is an old question with working answers, I missed international format support. Based on the solution of simonobo, the altered character set includes a plus sign "+". International phone numbers are supported by this amendment as well.

虽然这是一个有工作答案的老问题,但我错过了国际格式支持。基于simonobo的解决方案,修改后的字符集包含一个加号“+”。此修正案也支持国际电话号码。

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

The Swift expressions are

Swift 表达式是

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

Which yields +12345671000 as a common international phone number format.

这产生 +12345671000 作为常见的国际电话号码格式。

回答by Christopher Wade Cantley

Here is the Swift version of this.

这是 Swift 版本。

import UIKit
import Foundation
var phoneNumber = " 1 (888) 555-5551    "
var strippedPhoneNumber = "".join(phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet))

回答by Jon Vogel

Swift version of the most popular answer:

最流行答案的 Swift 版本:

var newString = join("", oldString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet))

Edit: Syntax for Swift 2

编辑:Swift 2 的语法

let newString = oldString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")

Edit: Syntax for Swift 3

编辑:Swift 3 的语法

let newString = oldString.components(separatedBy: CharacterSet.decimalDigits.inverted).joined(separator: "")

回答by GregoryN

Thanks for the example. It has only one thing missing the increment of the scanLocation in case one of the characters in originalString is not found inside the numbers CharacterSet object. I have added an else {} statement to fix this.

谢谢你的例子。它只有一件事缺少 scanLocation 的增量,以防在数字 CharacterSet 对象中找不到 originalString 中的一个字符。我添加了一个 else {} 语句来解决这个问题。

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];
  }
  // --------- Add the following to get out of endless loop
  else {
     [scanner setScanLocation:([scanner scanLocation] + 1)];
  }    
  // --------- End of addition
}

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

回答by KumarS

It Accept only mobile number

它只接受手机号码

NSString * strippedNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"[^0-9]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [mobileNumber length])];

回答by kadam

It might be worth noting that the accepted componentsSeparatedByCharactersInSet:and componentsJoinedByString:-based answer is not a memory-efficient solution. It allocates memory for the character set, for an array and for a new string. Even if these are only temporary allocations, processing lots of strings this way can quickly fill the memory.

可能值得注意的是,接受componentsSeparatedByCharactersInSet:componentsJoinedByString:基于 - 的答案不是内存高效的解决方案。它为字符集、数组和新字符串分配内存。即使这些只是临时分配,以这种方式处理大量字符串也可以快速填满内存。

A memory friendlier approach would be to operate on a mutable copy of the string in place. In a category over NSString:

一种对内存更友好的方法是对字符串的可变副本进行操作。在 NSString 上的类别中:

-(NSString *)stringWithNonDigitsRemoved {
    static NSCharacterSet *decimalDigits;
    if (!decimalDigits) {
        decimalDigits = [NSCharacterSet decimalDigitCharacterSet];
    }
    NSMutableString *stringWithNonDigitsRemoved = [self mutableCopy];
    for (CFIndex index = 0; index < stringWithNonDigitsRemoved.length; ++index) {
        unichar c = [stringWithNonDigitsRemoved characterAtIndex: index];
        if (![decimalDigits characterIsMember: c]) {
            [stringWithNonDigitsRemoved deleteCharactersInRange: NSMakeRange(index, 1)];
            index -= 1;
        }
    }
    return [stringWithNonDigitsRemoved copy];
}

Profiling the two approaches have shown this using about 2/3 less memory.

分析这两种方法表明,使用大约 2/3 的内存。