我有一个NSString(电话号码),其中一些电话号码被格式化为带有括号和连字符。 我该如何从字符串中删除除数字以外的所有字符?
我有一个NSString(电话号码),其中一些电话号码被格式化为带有括号和连字符。 我该如何从字符串中删除除数字以外的所有字符?
虽然这是一个旧问题,但是有一个解决方案:
NSString *newString = [[origString componentsSeparatedByCharactersInSet:
[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
componentsJoinedByString:@""];
它将源字符串根据非数字字符进行拆分,然后使用空字符串分隔符重新组装。虽然不如逐个字符检索效率高,但代码更加简洁。
无需像其他答案中建议的那样使用正则表达式库--你需要使用的类名为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"
编辑:我已经更新了代码,因为原始代码是凭空想象的,我认为指导人们正确方向就足够了。看起来人们想要的是可以直接复制粘贴到他们的应用程序中的代码。
我也同意Michael Pelz-Sherman的解决方案比使用NSScanner
更合适,所以你可能想看一下它。
被采纳的答案对于问题来说过于复杂了。这个更简单:
NSString *pureNumbers = [[phoneNumberString componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];
这很好,但是这段代码在我的 iPhone 3.0 SDK 上无法工作。
如果我像你展示的这样定义 strippedString,当我尝试在 scanCharactersFromSet:intoString
调用后打印它时,会出现 BAD ACCESS 错误
。
如果我这样做:
NSMutableString *strippedString = [NSMutableString stringWithCapacity:10];
我的代码最终产生了一个空字符串,但是程序没有崩溃。
我不得不转而使用老派的C语言:
for (int i=0; i<[phoneNumber length]; i++) {
if (isdigit([phoneNumber characterAtIndex:i])) {
[strippedString appendFormat:@"%c",[phoneNumber characterAtIndex:i]];
}
}
尽管这是一个已有可行答案的老问题,但我错过了国际格式支持。基于simonobo的解决方案,修改后的字符集包括加号“+”。这个修正也支持国际电话号码。
NSString *condensedPhoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:
[[NSCharacterSet characterSetWithCharactersInString:@"+0123456789"]
invertedSet]]
componentsJoinedByString:@""];
Swift表达式是:
var phoneNumber = " +1 (234) 567-1000 "
var allowedCharactersSet = NSMutableCharacterSet.decimalDigitCharacterSet()
allowedCharactersSet.addCharactersInString("+")
var condensedPhoneNumber = phoneNumber.componentsSeparatedByCharactersInSet(allowedCharactersSet.invertedSet).joinWithSeparator("")
这会产生+12345671000作为常见的国际电话号码格式。
这是它的Swift版本。
import UIKit
import Foundation
var phoneNumber = " 1 (888) 555-5551 "
var strippedPhoneNumber = "".join(phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet))
最受欢迎答案的Swift版本:
var newString = join("", oldString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet))
编辑:适用于Swift 2的语法
let newString = oldString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("")
编辑:Swift 3的语法
let newString = oldString.components(separatedBy: CharacterSet.decimalDigits.inverted).joined(separator: "")
谢谢提供这个例子。唯一缺少的是在原始字符串中有一个字符未被发现在数字CharacterSet对象中时,扫描位置的增量。我添加了一个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"
只接受手机号码
NSString * strippedNumber = [mobileNumber stringByReplacingOccurrencesOfString:@"[^0-9]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [mobileNumber length])];
值得注意的是,使用componentsSeparatedByCharactersInSet:
和componentsJoinedByString:
方法来实现此功能并不是一种内存高效的解决方案。这会为字符集、数组和新字符串分配内存。即使这些只是临时分配,用这种方式处理大量字符串可能会迅速占满内存。
更加内存友好的方法是在原地对可变副本进行操作。可以在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];
}
对这两种方法进行分析表明,使用的内存约减少了2/3。
NSCharacterSet *myCharSet = [NSCharacterSet characterSetWithCharactersInString:@"charactersGoHere"]
来创建自己的定制 NSCharacterSet。 - abc123NSString *pureNumbers = [pureNumbers stringByTrimmingCharactersInSet: [NSCharacterSet decimalDigitCharacterSet] invertedSet]
不起作用? - Thomas BesnehardNSMutableCharaterSet
并将decimalDigitCharacterSet
,uppercaseLetterCharacterSet
和lowercaseLetterCharacterSet
传递给formUnionWithCharacterSet:
来构建一个字符集。请注意,letterCharacterSet
也包括标记,因此使用小写和大写版本。 - kadam