Reputation: 241
What is the easiest way to format a string like "1234567890123456789" to "1234 5678 9012 3456 789" in iOS?
Upvotes: 1
Views: 2692
Reputation: 705
Try this:
-(NSString *) correctString:(NSString *) anyStr {
NSMutableString *str = [NSMutableString stringWithString:anyStr];
int indx=4;
while (indx<str.length) {
[str insertString:@" " atIndex:indx];
indx +=5;
}
anyStr=str;
return anyStr;
}
Upvotes: 3
Reputation: 15991
Here is a Swift extension:
extension String {
var pairs: [String] {
var result: [String] = []
let chars = Array(characters)
for index in 0.stride(to: chars.count, by: 4) {
result.append(String(chars[index..<min(index+4, chars.count)]))
}
return result
}
}
To use:
let string : String = "1234567890123456789"
let finalString = string.pairs.joinWithSeparator(" ") //1234 5678 9012 3456 789
print(finalString)
For Swift 3:
extension String {
var pairs: [String] {
var result: [String] = []
let chars = Array(characters)
for index in stride(from: 0, to: chars.count, by: 4){
result.append(String(chars[index..<min(index+4, chars.count)]))
}
return result
}
}
Upvotes: 0
Reputation: 2107
I propose to use NSString category. In not ARC just add autorelease after self copy. My variant will not add spaces after last digits quarter if it is not nescessary. Applicable to use in UITextField.
- (NSString *)creditCardNumberFormatedString {
NSString *string = [self copy];
NSUInteger length = string.length;
if (length >= 17) {
string = [string substringToIndex:16];
length = 16;
}
BOOL isSpaceRequired = YES;
if (length == 4) {
isSpaceRequired = NO;
}
NSString *newString = [NSString new];
while (string.length > 0) {
NSString *subString = [string substringToIndex:MIN(string.length, 4)];
newString = [newString stringByAppendingString:subString];
if (subString.length == 4 && isSpaceRequired) {
newString = [newString stringByAppendingString:@" "];
}
string = [string substringFromIndex:MIN(string.length, 4)];
if (string.length <= 4) {
isSpaceRequired = NO;
}
}
return newString;
}
Upvotes: 0
Reputation: 438122
For that particular format, you could do something like the following, which extracts the individual substrings:
NSString *string = @"1234567890123456789";
NSMutableArray *array = [NSMutableArray array];
for (NSInteger i = 0; i < [string length]; i += 4)
[array addObject:[string substringWithRange:NSMakeRange(i, MIN(4, [string length] - i))]];
NSString *result = [array componentsJoinedByString:@" "];
The thing is, not all credit cards conform to the xxxx xxxx xxxx xxxx format. E.g., Amex uses a xxxx xxxxxx xxxxx format. You really should look at the first digits of the card, determine the type of card, and format it accordingly.
You asked if you could do it with a regular expression. Consider this regex:
NSString *result = [string stringByReplacingOccurrencesOfString:@"^[\\s-]*([0-9]{4})[\\s-]*([0-9]{4})[\\s-]*([0-9]{4})[\\s-]*([0-9]{4})[\\s-]*([0-9]{3})[\\s-]*$"
withString:@"$1 $2 $3 $4 $5"
options:NSRegularExpressionSearch
range:NSMakeRange(0, [string length])];
That will convert any of the following:
@"1234567890123456789" @"1234-5678-9012-3456-789" @" 1234567890123456789 "
into:
@"1234 5678 9012 3456 789"
While you could use regular expression, it's sufficiently opaque that I wouldn't particularly advise it. But it can be done.
Upvotes: 3
Reputation: 186
I wrote code.
NSMutableString *string = @"1234567890123456789";
NSInteger *ip = 4;
for (NSInteger i = 0; i*4 < [string length] ; i++)
{
[string insertString:@" " atIndex:ip];
ip = ip+5;
}
Upvotes: 0