I am going to create a CSV file programmatically and would like to properly escape my strings before writing them.
I assume I'll need to escape commas and probably need to surround each value in single or double quotes (and thus will need to escape those too). Plus any carriage return / new line constants.
I was going to write it all myself but then found this in Objective-C and said why not just convert it, as it looks quite thorough:
-(NSString *)escapeString:(NSString *)s
{
NSString * escapedString = s;
BOOL containsSeperator = !NSEqualRanges([s rangeOfString:@","], NSMakeRange(NSNotFound, 0));
BOOL containsQuotes = !NSEqualRanges([s rangeOfString:@"\""], NSMakeRange(NSNotFound, 0));
BOOL containsLineBreak = !NSEqualRanges([s rangeOfString:@"\n"], NSMakeRange(NSNotFound, 0));
if (containsQuotes) {
escapedString = [escapedString stringByReplacingOccurrencesOfString:@"\"" withString:@"\"\""];
}
if (containsSeperator || containsLineBreak) {
escapedString = [NSString stringWithFormat:@"\"%@\"", escapedString];
}
return escapedString;
}
Before I go and convert this, however, I wanted to ask the community if there is an easier way now that we're in Swift 2. Have any interesting/new changes occurred for strings that I might want to consider in favor of "Swiftifying" the above code? I did some Googling but nothing jumped out at me and I want to really make sure I do a good job here. :-)
Thanks!
You could reduce your code and save it as a String extension:
extension String {
func escapeString() -> String {
var newString = self.stringByReplacingOccurrencesOfString("\"", withString: "\"\"")
if newString.containsString(",") || newString.containsString("\n") {
newString = String(format: "\"%@\"", newString)
}
return newString
}
}
Also few tests:
var test1 = String("Test")
test1.escapeString() // produces Test
var test2 = String("Test\n")
test2.escapeString() // produces "Test\n"
var test3 = String("Test, Test2")
test3.escapeString() // produces "Test, Test2"