Skip to content

Instantly share code, notes, and snippets.

@luisgerhorst
Last active August 29, 2015 13:55
Show Gist options
  • Save luisgerhorst/8697740 to your computer and use it in GitHub Desktop.
Save luisgerhorst/8697740 to your computer and use it in GitHub Desktop.

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment