Reputation: 9541
I want to format any text that is placed into a NSTextField/UITextField to look like
###-###-####
Here are some possible inputs
1112223333
111.222.3333
(111)222-3333
(111) 2223333
Upvotes: 4
Views: 742
Reputation: 652
Regular expressions are your friend:
NSString * reformat( NSString * number )
{
NSRegularExpression * noDigits =
[ NSRegularExpression regularExpressionWithPattern: @"\\D" options: 0 error: NULL ] ;
NSString * onlyDigits = [ noDigits stringByReplacingMatchesInString: number
options: 0
range: NSMakeRange ( 0, number.length )
withTemplate: @"" ] ;
NSRegularExpression * phoneNumberPattern =
[ NSRegularExpression regularExpressionWithPattern: @"^(\\d\\d\\d)(\\d\\d\\d)(\\d\\d\\d\\d)$"
options: 0
error: NULL ] ;
NSString * result = [ phoneNumberPattern stringByReplacingMatchesInString: onlyDigits
options: 0
range: NSMakeRange( 0, onlyDigits.length )
withTemplate: @"$1-$2-$3" ] ;
return result ;
}
You might want to check out some alternatives to the last pattern-matching replacement in case you are confronted with something other than 10 digits. Alternatively, put in a length check right afteronlyDigits
is computed.
Upvotes: 1
Reputation: 1965
Try this method
-(void)NumberFormatter:(NSString *)originalString
{
NSCharacterSet * set = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ"];
if ([originalString rangeOfCharacterFromSet:set].location == NSNotFound)
{
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)];
}
}
if ([strippedString length]<10) {
NSLog(@"it is invalid string ,must contain atleast 10 numbers");
}
else
{
NSString *finalstring= [NSString stringWithFormat:@"%@-%@-%@",[strippedString substringWithRange:NSMakeRange(0, 3)],[strippedString substringWithRange:NSMakeRange(3, 3)],[strippedString substringFromIndex:6]];
NSLog(@"This is the formatted number==%@",finalstring);
}
}
else
NSLog(@"string is invalid,It contains characters");
}
Upvotes: 0
Reputation: 2703
I've tested this code and it works for all of your examples:
- (NSString *)convertNumber:(NSString *)input {
NSMutableString *result = [NSMutableString stringWithCapacity:15];
NSScanner *scanner = [NSScanner scannerWithString:input];
NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:@"1234567890"];
NSString *temp;
NSInteger location = 0;
// Get first group
[scanner scanUpToCharactersFromSet:numbers intoString:&temp];
location = [scanner scanLocation];
[scanner scanCharactersFromSet:numbers intoString:&temp];
[result appendString:temp];
if ([scanner scanLocation] < location + 4) {
// Only scanned three numbers - get second group
[scanner scanUpToCharactersFromSet:numbers intoString:&temp];
location = [scanner scanLocation];
[scanner scanCharactersFromSet:numbers intoString:&temp];
[result appendString:temp];
if ([scanner scanLocation] < location + 4) {
// Only scanned three numbers - get last group
[scanner scanUpToCharactersFromSet:numbers intoString:&temp];
[scanner scanCharactersFromSet:numbers intoString:&temp];
[result appendString:temp];
}
} else if ([scanner scanLocation] < location + 7) {
// Scanned six numbers - get last group
[scanner scanUpToCharactersFromSet:numbers intoString:&temp];
[scanner scanCharactersFromSet:numbers intoString:&temp];
[result appendString:temp];
}
// Add dashes
if ([result length] > 6) {
[result insertString:@"-" atIndex:3];
[result insertString:@"-" atIndex:7];
}
return result;
}
Any quantity of non-numeric characters (or none) between the groups of 3, 3 and 4 will be ignored.
Warning: it may leak all over the place, and could crash if given unexpected input.
Upvotes: 3