【问题标题】:Custom format for a NSNumber to NSString conversionNSNumber 到 NSString 转换的自定义格式
【发布时间】:2023-04-08 16:55:02
【问题描述】:

我的应用程序中有一个UITextField,它接收一个号码。

我希望这个数字以特定格式表示,例如:(62) 1234 1234

问题是:我已经控制了方法-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string,但我不知道如何制作这个“面具”

目前我正在这样做:

string = [textField.text stringByReplacingCharactersInRange:range withString:string];
string = [[string componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:@""];

NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:string];
NSLog(@"%@", myNumber);

在这段代码的末尾我有两件事:

  1. string : 我的文本的字符串表示形式(例如 6212341234 作为 NSString
  2. myNumber : 此字符串的编号(例如 6212341234 作为 NSNumber

如何根据myNumberstring 创建此字符串:(62) 1234 1234

编辑

回复 rdelmar 问题:

这个数字可以有 10 或 11 个数字,我打算像这样分开它们: (62) 1234 1234(62) 12345 1234

【问题讨论】:

  • 数字总是10位数吗?而且,您是否总是想按照上面显示的方式将其分开?
  • 这真的是电话号码吗?从您尝试实现的格式来看,看起来像。如果是这样,将其视为字符串并使用子字符串。
  • 这不是电话号码,现在想起来可以当作一个。但是我该怎么做呢?
  • 如果是电话号码,您可以根据“(62)”或“(4)”之类的区号进行推理,然后根据约定对其余部分进行分组。就分组而言,不同区域设置的电话号码格式不同。它也与正常的数字分组有很大不同,即不是基于千数之类的数量。
  • 好吧...我明白你的意思了。但我仍然不知道如何实施这个解决方案。你能制定一个答案并将其作为答案发布吗?

标签: ios nsstring nsnumber nsnumberformatter


【解决方案1】:

你可以使用NSRegularExpression...

- (NSString *) formattedString:(NSString *)inputString
{
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?:([0-9]{2})([0-9]{5})([0-9]{4}))|(?:([0-9]{0,2}+)([0-9]{0,4}+)([0-9]{0,4}+))" options:0 error:&error];
    NSArray *components = [NSArray array];
    NSArray *matches = [regex matchesInString:inputString options:0 range:NSMakeRange(0, [inputString length])];
    NSTextCheckingResult *match = [matches objectAtIndex:0];
    for ( NSUInteger i = 1; i <= 3; ++i )
    {
        NSRange range = [match rangeAtIndex:i];
        if ( NSNotFound == range.location )
        {
            break;
        }
        components = [components arrayByAddingObject:[inputString substringWithRange:range]];
    }
    if ( 0 == [components count] )
    {
        for ( NSUInteger i = 4; i <= 6; ++i )
        {
            NSRange range = [match rangeAtIndex:i];
            components = [components arrayByAddingObject:[inputString substringWithRange:range]];
        }
    }
    return [NSString stringWithFormat:@"(%@) %@ %@",
            [components objectAtIndex:0],
            [components objectAtIndex:1],
            [components objectAtIndex:2]];
}


- (void) testFormatting
{
    NSLog(@"%@", [self formattedString:@"62123451234"]);
    NSLog(@"%@", [self formattedString:@"6212341234"]);
    NSLog(@"%@", [self formattedString:@"621234123"]);
    NSLog(@"%@", [self formattedString:@"62123412"]);
    NSLog(@"%@", [self formattedString:@"6212341"]);
    NSLog(@"%@", [self formattedString:@"621234"]);
    NSLog(@"%@", [self formattedString:@"62123"]);
    NSLog(@"%@", [self formattedString:@"6212"]);
    NSLog(@"%@", [self formattedString:@"621"]);
    NSLog(@"%@", [self formattedString:@"62"]);
    NSLog(@"%@", [self formattedString:@"6"]);
}

调用testFormatting方法的结果是:

(62) 12345 1234
(62) 1234 1234
(62) 1234 123
(62) 1234 12
(62) 1234 1
(62) 1234 
(62) 123 
(62) 12 
(62) 1 
(62)  
(6)  

这样您可以将中间字符串传递给格式化程序,它会尝试做正确的事情。

【讨论】:

    【解决方案2】:

    你可以这样做(对于 10 位数字):

    -(NSString *)formatString:(NSString *) input {
        NSString *part1 = [NSString stringWithFormat:@"(%@)",[input substringToIndex:2]];
        NSString *part2 = [input substringWithRange:NSMakeRange(2, 4)];
        NSString *part3 = [input substringWithRange:NSMakeRange(6, 4)];
        NSString *formatted = [NSString stringWithFormat:@"%@ %@ %@",part1,part2,part3];
        return formatted;
    
    }
    

    要处理 10 位或 11 位数字,您必须放入 if 子句来测试长度,然后相应地更改 part2 和 part3 的范围。

    编辑后:这样的事情怎么样。我认为这是可以做到的。它会在您键入时将其分解为 (xx) xxxx xxxx,如果您键入另一个数字,它会将其分解为 (xx) xxxx xxxx。任何进一步的输入都将被忽略。

    -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
        if (textField.text.length == 0)
         textField.text = [NSString stringWithFormat:@"(%@",textField.text];
    
        if (textField.text.length == 3)
            textField.text = [NSString stringWithFormat:@"%@) ",textField.text];
    
        if (textField.text.length == 9)
            textField.text = [NSString stringWithFormat:@"%@ ",textField.text];
    
        if (textField.text.length == 14) {
            NSString *part1 = [textField.text substringToIndex:9];
            part1 = [part1 stringByAppendingString:[textField.text substringWithRange:NSMakeRange(10, 1)]];
            NSString *part2 = [textField.text substringWithRange:NSMakeRange(11, 3)];
            textField.text = [NSString stringWithFormat:@"%@ %@",part1,part2];
        }
    
        if (textField.text.length > 14)
            return NO;
    
        return YES;
    }
    

    【讨论】:

    • 在我的应用程序中,字符串格式是在用户键入新数字的同时进行的。因此,我没有 10-11 位数字的完整字符串。因为substringWithRange: 不会工作
    • 你应该在一开始就提到这一点。我认为没有任何方法可以在您键入时完全正确,因为无法知道用户是要输入 11 位数字还是 10 位数字。因此,在输入最后一位数字之前,无法确定最后 2 部分之间的间隔。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多