How To Find A Substring In Range of a Swift String

Swift Ranges are wildly different than NSRange in Objective-C. I therefore find myself always spending way more time working with Swift Ranges than I ever think I would! Of course, in retrospect, Swift Ranges make a lot of sense, but they’re hard to work with out of the box.

As a demo, here is how you get a substring at a specific start and end point:

var str = "Hello, playground"

let rangeOfHello = Range(start: str.startIndex,
                         end: advance(str.startIndex, 5))
let helloStr = str.substringWithRange(rangeOfHello)
helloStr //"Hello"

As you can see, you can’t just specify a range with Ints! You need to use the String’s startIndex and endIndex properties (of type String.Index not Int), to work specifically with ranges.

To get a range beyond the startIndex, you can use the advance function as demoed above. You can also advance in the negative direction, so if you need to get the index in relation to the endIndex, just use a negative value as follows:

let dob = "01/01/2000"

let rangeOfYear = Range(start: (advance(dob.endIndex, -4)),
                        end: dob.endIndex)
let yearStr = dob.substringWithRange(rangeOfYear)
yearStr // "2000"

Again, in retrospect, I find Swift Ranges to be very clean and elegant. Just have to remember how to use them every time!

Enjoy the article? Join over 14,500+ Swift developers and enthusiasts who get my weekly updates.

  • Alak

    I find Swift Range very (too) verbose.

  • Jeff

    Thanks for writing this! Maybe one day they’ll let us just specify a start and end index.

  • Davide De Franceschi

    Still not optimal, but given the quite different reality of Swift String from other usual Strings I think this is acceptable:

    let helloStr = str[str.startIndex ..< advance(str.startIndex, 5)]
    let yearStr = dob[advance(dob.endIndex, -4) ..< str.endIndex]

  • Guest

    Otherwise you can still extend String with new Int and Range substring and it will work as desired

  • Michael Prenez-Isbell
  • Mathew Howe

    Hi Natasha –

    Im fairly new to swift and trying to code up some kind of filtering logic for RSS feeds.
    I am using the below code to look for certain key words within news streams etc.
    However, I am trying to make the ‘key word search’ functionality more dynamic – So user inputs the keywords, these are stored in a container such as an array. The app then searches the feeds for all words in this array of ‘key words’.

    var myString = “Swift is really easy!”
    if myString.rangeOfString(“easy”) != nil {
    println(“Exists!”)
    }

  • Fustigador

    Waaaaaay too verbose for such a common task like working with Strings, and way to “clunky” for a company that “focus on excellency”. I think Swift has a LOT to improve.

  • klogram

    This post was quite helpful. Thanks.

  • Vince O’Sullivan

    Treating the string as an array of characters also works well:

    let yearStr = String(Array(dob.characters)[3…4])

  • codingTheHole

    I agree that this is a ridiculously longwinded method, but it’s two lines of code to turn this into a String extension in the form of str.substringWithMoreConvenientRangeInts(Int, Int). I think writing that extension and saving it as a code snippet took roughly as long as it took to write this post.