Search code examples
swiftdo-catch

Returning String from a do-catch statement


I was trying to translate the code from swift 2 to swift 4 and came across this error

Errors thrown from here are not handled

So I did this but now it tells me to return a string. Any idea how to do this?

func formatSentence(sentence:String) -> String
{
    do {
        let regex = try NSRegularExpression(pattern: "\\W+", options: .caseInsensitive)
        let modifiedString = regex.stringByReplacingMatches(in: sentence, options: [], range: NSRange(location: 0,length: sentence.count), withTemplate: "")

    } catch {
        print(error)
    }

    //I tried adding it here the return modifiedString but gives me error
}

This is what the original function looks like

func formatSentence(sentence:String) -> String
{
    let regex = NSRegularExpression(pattern: "\\W+", options: .caseInsensitive)//NSRegularExpression(pattern:"\\W+", options: .CaseInsensitive, error: nil)
    let modifiedString = regex.stringByReplacingMatches(in: sentence, options: [], range: NSRange(location: 0,length: sentence.count), withTemplate: "")

    return modifiedString
}

Solution

  • It depends upon how you want to handle the error condition. There are a few options:

    1. You could make it return String?, where nil means there was an error:

      func formatSentence(_ sentence: String) -> String? {
          do {
              let regex = try NSRegularExpression(pattern: "\\W+", options: .caseInsensitive)
              let range = NSRange(sentence.startIndex..., in: sentence)
              return regex.stringByReplacingMatches(in: sentence, range: range, withTemplate: "")
          } catch {
              print(error)
              return nil
          }
      }
      

      And then you'd do something like:

      guard let sentence = formatSentence(string) else { 
          // handle error here
          return
      }
      
      // use `sentence` here
      
    2. You could define your function as one that throws the error if it encounters one:

      func formatSentence(_ sentence: String) throws -> String {
          let regex = try NSRegularExpression(pattern: "\\W+", options: .caseInsensitive)
          let range = NSRange(sentence.startIndex..., in: sentence)
          return regex.stringByReplacingMatches(in: sentence, range: range, withTemplate: "")
      }
      

      And then you'd catch errors at the calling point:

      do {
          let sentence = try formatSentence(string)
      
          // use `sentence` here
      } catch {
          // handle error here
          print(error)
      }
      
    3. Or, given that you know your pattern is valid, you could use try! knowing that it cannot fail:

      func formatSentence(_ sentence: String) -> String {
          let regex = try! NSRegularExpression(pattern: "\\W+", options: .caseInsensitive)
          let range = NSRange(sentence.startIndex..., in: sentence)
          return regex.stringByReplacingMatches(in: sentence, range: range, withTemplate: "")
      }
      

      And then you can just do:

      let sentence = formatSentence(string)
      

      You only use this last pattern if you know, with 100% confidence, that NSRegularExpression cannot fail given your regex pattern (such as in this situation).


    As an aside, you might cut the Gordian knot and just use replacingOccurrences with .regularExpression option:

    func formatSentence(_ sentence: String) -> String {
        return sentence.replacingOccurrences(of: "\\W+", with: "", options: .regularExpression)
    }