3

我是 Objective-C 的新手,但在其他高级语言方面经验丰富。我想通过删除所有非数字字符来规范化字符串。换句话说,给定输入字符串“206-555-1212”,归一化结果应该是“2065551212”。下面的代码片段有效,但考虑到我在其他语言方面的经验,这似乎有点矫枉过正。有更好的方法吗?

编辑:输入字符串“(206) 555-1212”、“206.555.1212”、“206 555 1212”等也应该返回相同的标准化结果。

NSString * normalize(NSString * number)
{
    NSString *normalizedNumber = @"";
    NSString *tmpString = nil;

    NSRange searchRange;
    NSRange resultRange;
    searchRange.location = 0;
    searchRange.length = number.length;

    while (0 < searchRange.length)
    {
        resultRange = [number rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]
                                        options:NSLiteralSearch
                                          range:searchRange];
        tmpString = [number substringWithRange:resultRange];
        normalizedNumber = [normalizedNumber stringByAppendingString:tmpString];
        searchRange.location = resultRange.location + resultRange.length;
        searchRange.length = number.length - searchRange.location;
    }

    return normalizedNumber;
}
4

6 回答 6

12

Resh32 在他们对类似问题的回答中建议使用此代码:

NSString * val = @"(555) 555-555 Office";
NSString * strippedNumber = [val stringByReplacingOccurrencesOfString:@"[^0-9]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [val length])];
NSLog(@"%@", strippedNumber);
于 2013-03-20T05:23:26.997 回答
8

所有这些答案都没有解决问题的“删除所有非数字字符”部分。这是一个简单的方法:

NSString *normalize(NSString *number) {
    NSMutableCharacterSet *nonNumberCharacterSet = [NSMutableCharacterSet decimalDigitCharacterSet];
    [nonNumberCharacterSet invert];

    return [[number componentsSeparatedByCharactersInSet:nonNumberCharacterSet] componentsJoinedByString:@""];
}
于 2013-03-20T06:10:32.030 回答
1

我有一个小帮手方法:

+ (NSString *)strip:(NSString *)str keep:(NSString *)chars {
    NSCharacterSet *cs = [NSCharacterSet characterSetWithCharactersInString:chars];
    NSMutableString *res = [NSMutableString stringWithString:str];
    for (int i = [res length] - 1; i >= 0; i--) {
        if (![cs characterIsMember:[res characterAtIndex:i]]) {
            [res deleteCharactersInRange:NSMakeRange(i, 1)];
        }
    }

    return res;
}

可以这样调用:

NSString *cleanString = [UtilityClass strip:originalString keep:@"0123456789+*#"];
于 2013-03-20T05:23:52.933 回答
1

即使这个也可以:

NSString *s = @"234-1243-123";
NSString *ss=[[s componentsSeparatedByString:@"-"] componentsJoinedByString:@""];
于 2013-03-20T05:35:59.940 回答
0

一种选择是创建一个 NSFormatter 子类来封装逻辑,或者使用开源的。PhoneNumberFormatter看起来很有希望,并且可以让您删除格式,如下所示:

PhoneNumberFormatter *formatter = [[PhoneNumberFormatter alloc] init];
id objectValue;
NSError *error;
[formatter getObjectValue:&objectValue forString:@"1 (234) 567-8900" errorDescription:&error];
// objectValue = @"12345678900"
于 2013-03-20T05:21:38.583 回答
0

这取决于您的具体目标。

如果您确实确定您的所有输入都将是 form ,这与从字符串中删除所有空格(答案与已发布的答案相似)xxx-xxx-xxxx相同的基本问题,只是不是删除空格,而是删除字符. 总结:使用(在这种情况下有点过度杀戮,但可能足以代替下面的技术)。--[NSString stringByReplacingOccurrencesOfString:withString:]-[NSString componentsSeparatedByCharactersInSet:]NSScanner

如果您尝试使用任意格式清理电话号码,那么您使用的方法是合理的,但是使用 NSScanner 会稍微更惯用,如“从 NSString 中删除除数字之外的所有数字”的答案中所述。另请注意,如果您正在构建一个字符串(就像您的代码一样),使用 NSMutableString-appendString:而不是-[NSString stringByAppendingString:].

rmaddy 的方法在这里也是一个很好的方法,但需要注意的是,它作为 NSString 上的一个类别可能最有意义,其名称遵循 Apple 的约定。

请注意,这些技术都不会验证电话号码,只会天真地从字符串中提取 base-10 数字。

最强大的解决方案是使用某种形式的专用电话号码检测器(la Stuart 的链接PhoneNumberFormatter)。

但是,如果您要做的是识别和提取电话号码而不必规范您的数据,Apple 提供了一个可以为此目的配置的类NSDataDetector 。一个简单的示例如下所示:

NSError *error = nil;
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypePhoneNumber error:&error];

if(!detector) {
   NSLog(@"Error creating phone number detector: %@", [error localizedDescription]);
   return;
}

NSString *phoneNumberString = @"(555) 555-5555";

NSArray *matches = [detector matchesInString:phoneNumberString
                             options:0
                               range:NSMakeRange(0, [phoneNumberString length])];

if([matches count] < 1) {
   NSLog(@"No phone numbers found!");
   return;
}

NSTextCheckingResult *match = [matches lastObject];
if([match resultType] != NSTextCheckingTypePhoneNumber) {
    NSLog(@"Matched something, but not a phone number!");
    return;
}

NSString *phoneNumber = [match phoneNumber];
NSLog(@"Matched phone number: %@", phoneNumber);
于 2013-03-20T06:05:59.790 回答