Search code examples
iosswiftswift2ios9

Escaping Strings in Swift


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!


Solution

  • 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"