Search code examples
swift

How to remove smart quotes from a string?


I have a string like this:

let muString = "\n\nFebruary 11, 2012\n\nThis natural-color image showing Acme Inc\'s logo... bla bla bla “Mount Everest”... bla bla 'Black Viper' ... bla bla. \"Naja\""

In other words, I have smart quotes

` ´ ‘ ’ “ ”

(note: SO is not rendering correctly the previous characters. I mean they are opening and closing curly single and double quotes).

and also double quotes and I want to replace everything with a single plain ASCII quote.

I have created this extension:

extension String {
  func plainText() -> String {
    var newString = self.replacingOccurrences(of: "\u{0060}", with: "'")
    newString = self.replacingOccurrences(of: "\u{00b4}", with: "'")
    newString = self.replacingOccurrences(of: "\u{2018}", with: "'")
    newString = self.replacingOccurrences(of: "\u{2019}", with: "'")
    newString = self.replacingOccurrences(of: "\u{201c}", with: "'")
    newString = self.replacingOccurrences(of: "\u{201d}", with: "'")
    newString = self.replacingOccurrences(of: "\"", with: "'")
    return newString
  }
}

But doing

print (myString.plainText())

gives me the same as myString alone.

In other words, the extension cleans nothing.

Any ideas?


Solution

  • So replacingOccurrences returns a new string. Calling it on self inside the function means that you're always calling it on the original string itself. That means only your last call to replacingOccurrences is actually used. Instead of always calling it on replacingOccurrences on self, you should always call it on newString:

    extension String {
      func plainText() -> String {
        var newString = self.replacingOccurrences(of: "\u{0060}", with: "'")
        newString = newString.replacingOccurrences(of: "\u{00b4}", with: "'")
        newString = newString.replacingOccurrences(of: "\u{2018}", with: "'")
        newString = newString.replacingOccurrences(of: "\u{2019}", with: "'")
        newString = newString.replacingOccurrences(of: "\u{201c}", with: "'")
        newString = newString.replacingOccurrences(of: "\u{201d}", with: "'")
        newString = newString.replacingOccurrences(of: "\"", with: "'")
        return newString
      }
    }
    

    Or you could just chain the calls directly which is a lot cleaner.

    extension String {
      func plainText() -> String {
        return replacingOccurrences(of: "\u{0060}", with: "'")
              .replacingOccurrences(of: "\u{00b4}", with: "'")
              .replacingOccurrences(of: "\u{2018}", with: "'")
              .replacingOccurrences(of: "\u{2019}", with: "'")
              .replacingOccurrences(of: "\u{201c}", with: "'")
              .replacingOccurrences(of: "\u{201d}", with: "'")
              .replacingOccurrences(of: "\"", with: "'")
      }
    }