Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 从Obj-C中的字符串中提取数字_Objective C_String_Nsstring_Normalization - Fatal编程技术网

Objective c 从Obj-C中的字符串中提取数字

Objective c 从Obj-C中的字符串中提取数字,objective-c,string,nsstring,normalization,Objective C,String,Nsstring,Normalization,我不熟悉Objective-C,但对其他高级语言有经验。我想通过删除所有非数字字符来规范化字符串。换句话说,给定输入字符串“206-555-1212”,标准化结果应为“2065551212”。下面的代码片段可以工作,但考虑到我在其他语言方面的经验,这似乎有些过头了。有更好的方法吗 编辑:输入字符串“(206)555-1212”、“206.555.1212”、“206 555 1212”等也应返回相同的标准化结果 NSString * normalize(NSString * number) {

我不熟悉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;
}
NSString*规范化(NSString*编号)
{
NSString*normalizedNumber=@;
NSString*tmpString=nil;
NSRange搜索范围;
NSRange resultRange;
searchRange.location=0;
searchRange.length=number.length;
而(0
一个选项是创建NSFormatter子类来封装逻辑,或者使用开源的NSFormatter子类。看起来很有希望,并允许您按如下方式删除格式:

PhoneNumberFormatter *formatter = [[PhoneNumberFormatter alloc] init];
id objectValue;
NSError *error;
[formatter getObjectValue:&objectValue forString:@"1 (234) 567-8900" errorDescription:&error];
// objectValue = @"12345678900"

Resh32建议将此代码用于类似的问题:

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

我有一个小助手方法:

+ (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+*#"];
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);

即使是这一个也会起作用:

NSString *s = @"234-1243-123";
NSString *ss=[[s componentsSeparatedByString:@"-"] componentsJoinedByString:@""];

这取决于你的具体目标

如果您确实确定所有输入的格式都是
xxx xxx xxxx
,则这是与相同的基本问题(答案与已发布的答案类似),只是您没有删除空格,而是删除了
-
字符。小结:使用
-[NSString-stringByReplacingOccurrencesOfString:with-string://code>(
-[NSString-components-separatedbycharactersinset://code>在这种情况下略胜一筹,但可能足以替代下面的
NSScanner
技术)

如果您试图使用任意格式对电话号码进行清理,您使用的方法是合理的,但是使用NSScanner(如中所述)稍微更为惯用。还请注意,如果您正在构建字符串(就像您的代码一样),那么使用NSMutableString和
-appendString:
比使用
-[NSString stringByAppendingString:
更有效

这种方法在这里也是一种很好的方法,但需要注意的是,作为NSString上的一个类别,它可能最有意义,其名称遵循苹果的惯例

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

最可靠的解决方案是使用某种形式的专用电话号码检测器(la Stuart's链接)

然而,如果你想做的是识别和提取电话号码,而不必规范化你的数据,苹果提供了一个类,可以为此进行配置。一个简单的例子如下所示:

NSString *cleanString = [UtilityClass strip:originalString keep:@"0123456789+*#"];
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);
NSError*error=nil;
NSDataDetector*detector=[NSDataDetector dataDetectorWithTypes:NSTextCheckingTypePhoneNumber错误:&错误];
如果(!检测器){
NSLog(@“创建电话号码检测器时出错:%@,[Error localizedDescription]);
返回;
}
NSString*phoneNumberString=@“(555)555-5555”;
NSArray*matches=[检测器匹配安装:phoneNumberString
选项:0
范围:NSMakeRange(0,[phoneNumberString长度]);
如果([匹配计数]<1){
NSLog(@“找不到电话号码!”);
返回;
}
NSTextCheckingResult*match=[matches lastObject];
如果([match resultType]!=NSTextCheckingTypePhoneNumber){
NSLog(@“匹配了一些东西,但没有电话号码!”);
返回;
}
NSString*phoneNumber=[匹配phoneNumber];
NSLog(@“匹配的电话号码:%@”,电话号码);

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

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

    return [[number componentsSeparatedByCharactersInSet:nonNumberCharacterSet] componentsJoinedByString:@""];
}

+1这个。简单,不涉及不必要的1字符子字符串创建等。谢谢你,我希望这是最简单的方法。Sunny告诉我们,你从哪里学会了这种极好的提取方法?我已经编辑了我的答案,请查看。@AnoopVaidya smart Sunny可能从这里学到了->