The string ...
A,"B,","my Name is ""Alf"", hello",
,C,,
with the delimiter ,
becomes ...
[
[
"A",
"B,",
"my Name is \"Alf\", hello",
"",
],
[
"",
"C",
"",
""
]
]
The string ...
A,"B,","my Name is ""Alf"", hello",
,C,,
with the delimiter ,
becomes ...
[
[
"A",
"B,",
"my Name is \"Alf\", hello",
"",
],
[
"",
"C",
"",
""
]
]
#import <Foundation/Foundation.h> | |
@interface NSArray (LGCSVParser) | |
+ (instancetype)arrayWithCSVString:(NSString *)csvString delimiter:(unichar)delimiter; | |
@end |
#import "NSArray+LGCSVParser.h" | |
@implementation NSArray (LGCSVParser) | |
+ (instancetype)arrayWithCSVString:(NSString *)csvString delimiter:(unichar)delimiter | |
{ | |
// Field | |
NSString * const fieldRegExPattern = [NSString stringWithFormat:@"(?<=^|%C)(\"(?:[^\"]|\"\")*\"|[^%C]*)", delimiter, delimiter]; // Via http://stackoverflow.com/questions/3268622/regex-to-split-line-csv-file - works very good. Handles double double quotes, fields containing a delimiter and starting and ending with double quotes, delimiter after double double quotes in field that starts and ends with double quotes. | |
NSRegularExpression * const fieldRegEx = [NSRegularExpression regularExpressionWithPattern:fieldRegExPattern options:0 error:nil]; | |
// Quotes at start and end of string. | |
NSRegularExpression * const quotesAtStartAndEndRegEx = [NSRegularExpression regularExpressionWithPattern:@"^\".+\"$" options:0 error:nil]; // Matches every string that starts and ends with double quotes and has something else in between. | |
NSMutableArray *array = [NSMutableArray array]; | |
NSArray *lines = [csvString componentsSeparatedByString:@"\n"]; | |
for (NSString *line in lines) { // For each line ... | |
NSMutableArray *lineArray = [NSMutableArray array]; // Will be filled with the fields. | |
NSArray *fieldMatches = [fieldRegEx matchesInString:line options:0 range:NSMakeRange(0,[line length])]; // Matches every field. | |
for (NSTextCheckingResult *fieldMatch in fieldMatches) { // Each field match ... | |
NSMutableString *field = [NSMutableString stringWithString:[line substringWithRange:[fieldMatch range]]]; // Get field string. | |
if ([quotesAtStartAndEndRegEx numberOfMatchesInString:field options:0 range: NSMakeRange(0, [field length])]) { // If field starts and ends with double quotes ... | |
[field deleteCharactersInRange:NSMakeRange(0, 1)]; // Remove first ... | |
[field deleteCharactersInRange:NSMakeRange([field length]-1, 1)]; // ... and last char. | |
} | |
[field replaceOccurrencesOfString:@"\"\"" withString:@"\"" options:0 range:NSMakeRange(0, [field length])]; // Replace all double double quotes by single quotes. | |
[lineArray addObject:field]; // Add final field string to line array. | |
} | |
[array addObject:lineArray]; // Add line array to array. | |
} | |
return array; // Return the array of arrays containing strings. | |
} | |
@end |