How can I use String substring in Swift 4? 'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator

SwiftSwift4

Swift Problem Overview


I have the following simple code written in Swift 3:

let str = "Hello, playground"
let index = str.index(of: ",")!
let newStr = str.substring(to: index)

From Xcode 9 beta 5, I get the following warning:

> 'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator.

How can this slicing subscript with partial range from be used in Swift 4?

Swift Solutions


Solution 1 - Swift

You should leave one side empty, hence the name "partial range".

let newStr = str[..<index]

The same stands for partial range from operators, just leave the other side empty:

let newStr = str[index...]

Keep in mind that these range operators return a Substring. If you want to convert it to a string, use String's initialization function:

let newStr = String(str[..<index])

You can read more about the new substrings here.

Solution 2 - Swift

Convert Substring (Swift 3) to String Slicing (Swift 4)

Examples In Swift 3, 4:

let newStr = str.substring(to: index) // Swift 3
let newStr = String(str[..<index]) // Swift 4

let newStr = str.substring(from: index) // Swift 3
let newStr = String(str[index...]) // Swift 4 

let range = firstIndex..<secondIndex // If you have a range
let newStr = = str.substring(with: range) // Swift 3
let newStr = String(str[range])  // Swift 4

Solution 3 - Swift

Swift 5, 4

Usage
let text = "Hello world"
text[0] // H
text[...3] // "Hell"
text[6..<text.count] // world
text[NSRange(location: 6, length: 3)] // wor
Code
import Foundation

public extension String {
  subscript(value: Int) -> Character {
    self[index(at: value)]
  }
}

public extension String {
  subscript(value: NSRange) -> Substring {
    self[value.lowerBound..<value.upperBound]
  }
}

public extension String {
  subscript(value: CountableClosedRange<Int>) -> Substring {
    self[index(at: value.lowerBound)...index(at: value.upperBound)]
  }

  subscript(value: CountableRange<Int>) -> Substring {
    self[index(at: value.lowerBound)..<index(at: value.upperBound)]
  }

  subscript(value: PartialRangeUpTo<Int>) -> Substring {
    self[..<index(at: value.upperBound)]
  }

  subscript(value: PartialRangeThrough<Int>) -> Substring {
    self[...index(at: value.upperBound)]
  }

  subscript(value: PartialRangeFrom<Int>) -> Substring {
    self[index(at: value.lowerBound)...]
  }
}

private extension String {
  func index(at offset: Int) -> String.Index {
    index(startIndex, offsetBy: offset)
  }
}

Solution 4 - Swift

Shorter in Swift 4/5:

let string = "123456"
let firstThree = String(string.prefix(3)) //"123"
let lastThree = String(string.suffix(3)) //"456"

Solution 5 - Swift

The conversion of your code to Swift 4 can also be done this way:

let str = "Hello, playground"
let index = str.index(of: ",")!
let substr = str.prefix(upTo: index)

You can use the code below to have a new string:

let newString = String(str.prefix(upTo: index))

Solution 6 - Swift

Swift5

(Java's substring method):

extension String {
    func subString(from: Int, to: Int) -> String {
       let startIndex = self.index(self.startIndex, offsetBy: from)
       let endIndex = self.index(self.startIndex, offsetBy: to)
       return String(self[startIndex..<endIndex])
    }
}

Usage:

var str = "Hello, Nick Michaels"
print(str.subString(from:7,to:20))
// print Nick Michaels

Solution 7 - Swift

substring(from: index) Converted to [index...]

Check the sample

let text = "1234567890"
let index = text.index(text.startIndex, offsetBy: 3)

text.substring(from: index) // "4567890"   [Swift 3]
String(text[index...])      // "4567890"   [Swift 4]

Solution 8 - Swift

Some useful extensions:

extension String {
    func substring(from: Int, to: Int) -> String {
        let start = index(startIndex, offsetBy: from)
        let end = index(start, offsetBy: to - from)
        return String(self[start ..< end])
    }
    
    func substring(range: NSRange) -> String {
        return substring(from: range.lowerBound, to: range.upperBound)
    }
}

Solution 9 - Swift

Example of uppercasedFirstCharacter convenience property in Swift3 and Swift4.

Property uppercasedFirstCharacterNew demonstrates how to use String slicing subscript in Swift4.

extension String {

   public var uppercasedFirstCharacterOld: String {
      if characters.count > 0 {
         let splitIndex = index(after: startIndex)
         let firstCharacter = substring(to: splitIndex).uppercased()
         let sentence = substring(from: splitIndex)
         return firstCharacter + sentence
      } else {
         return self
      }
   }

   public var uppercasedFirstCharacterNew: String {
      if characters.count > 0 {
         let splitIndex = index(after: startIndex)
         let firstCharacter = self[..<splitIndex].uppercased()
         let sentence = self[splitIndex...]
         return firstCharacter + sentence
      } else {
         return self
      }
   }
}

let lorem = "lorem".uppercasedFirstCharacterOld
print(lorem) // Prints "Lorem"

let ipsum = "ipsum".uppercasedFirstCharacterNew
print(ipsum) // Prints "Ipsum"

Solution 10 - Swift

You can create your custom subString method using extension to class String as below:

extension String {
    func subString(startIndex: Int, endIndex: Int) -> String {
        let end = (endIndex - self.count) + 1
        let indexStartOfText = self.index(self.startIndex, offsetBy: startIndex)
        let indexEndOfText = self.index(self.endIndex, offsetBy: end)
        let substring = self[indexStartOfText..<indexEndOfText]
        return String(substring)
    }
}

Solution 11 - Swift

I have written a string extension for replacement of 'String: subString:'

extension String {
    
    func sliceByCharacter(from: Character, to: Character) -> String? {
        let fromIndex = self.index(self.index(of: from)!, offsetBy: 1)
        let toIndex = self.index(self.index(of: to)!, offsetBy: -1)
        return String(self[fromIndex...toIndex])
    }
    
    func sliceByString(from:String, to:String) -> String? {
        //From - startIndex
        var range = self.range(of: from)
        let subString = String(self[range!.upperBound...])
        
        //To - endIndex
        range = subString.range(of: to)
        return String(subString[..<range!.lowerBound])
    }
    
}

> Usage : "Date(1511508780012+0530)".sliceByString(from: "(", to: "+") > > Example Result : "1511508780012"

PS: Optionals are forced to unwrap. Please add Type safety check wherever necessary.

Solution 12 - Swift

Creating SubString (prefix and suffix) from String using Swift 4:
let str : String = "ilike"
for i in 0...str.count {
    let index = str.index(str.startIndex, offsetBy: i) // String.Index
    let prefix = str[..<index] // String.SubSequence
    let suffix = str[index...] // String.SubSequence
    print("prefix \(prefix), suffix : \(suffix)")
}
Output
prefix , suffix : ilike
prefix i, suffix : like
prefix il, suffix : ike
prefix ili, suffix : ke
prefix ilik, suffix : e
prefix ilike, suffix : 
If you want to generate a substring between 2 indices , use :
let substring1 = string[startIndex...endIndex] // including endIndex
let subString2 = string[startIndex..<endIndex] // excluding endIndex

Solution 13 - Swift

When programming I often have strings with just plain A-Za-z and 0-9. No need for difficult Index actions. This extension is based on the plain old left / mid / right functions.

extension String {
    
    // LEFT
    // Returns the specified number of chars from the left of the string
    // let str = "Hello"
    // print(str.left(3))         // Hel
    func left(_ to: Int) -> String {
        return "\(self[..<self.index(startIndex, offsetBy: to)])"
    }
    
    // RIGHT
    // Returns the specified number of chars from the right of the string
    // let str = "Hello"
    // print(str.left(3))         // llo
    func right(_ from: Int) -> String {
        return "\(self[self.index(startIndex, offsetBy: self.length-from)...])"
    }
    
    // MID
    // Returns the specified number of chars from the startpoint of the string
    // let str = "Hello"
    // print(str.left(2,amount: 2))         // ll
    func mid(_ from: Int, amount: Int) -> String {
        let x = "\(self[self.index(startIndex, offsetBy: from)...])"
        return x.left(amount)
    }
}

Solution 14 - Swift

If you are trying to just get a substring up to a specific character, you don't need to find the index first, you can just use the prefix(while:) method

let str = "Hello, playground"
let subString = str.prefix { $0 != "," } // "Hello" as a String.SubSequence

Solution 15 - Swift

This is my solution, no warning, no errors, but perfect

let redStr: String = String(trimmStr[String.Index.init(encodedOffset: 0)..<String.Index.init(encodedOffset: 2)])
let greenStr: String = String(trimmStr[String.Index.init(encodedOffset: 3)..<String.Index.init(encodedOffset: 4)])
let blueStr: String = String(trimmStr[String.Index.init(encodedOffset: 5)..<String.Index.init(encodedOffset: 6)])

Solution 16 - Swift

Hope this will help little more :-

var string = "123456789"

If you want a substring after some particular index.

var indexStart  =  string.index(after: string.startIndex )// you can use any index in place of startIndex
var strIndexStart   = String (string[indexStart...])//23456789

If you want a substring after removing some string at the end.

var indexEnd  =  string.index(before: string.endIndex)
var strIndexEnd   = String (string[..<indexEnd])//12345678

you can also create indexes with the following code :-

var  indexWithOffset =  string.index(string.startIndex, offsetBy: 4)

Solution 17 - Swift

with this method you can get specific range of string.you need to pass start index and after that total number of characters you want.

extension String{
    func substring(fromIndex : Int,count : Int) -> String{
        let startIndex = self.index(self.startIndex, offsetBy: fromIndex)
        let endIndex = self.index(self.startIndex, offsetBy: fromIndex + count)
        let range = startIndex..<endIndex
        return String(self[range])
    }
}

Solution 18 - Swift

var str = "Hello, playground"
let indexcut = str.firstIndex(of: ",")
print(String(str[..<indexcut!]))
print(String(str[indexcut!...]))

You can try in this way and will get proper results.

Solution 19 - Swift

Hope it would be helpful.

extension String {
    func getSubString(_ char: Character) -> String {
        var subString = ""
        for eachChar in self {
            if eachChar == char {
                return subString
            } else {
                subString += String(eachChar)
            }
        }
        return subString
    }
}


let str: String = "Hello, playground"
print(str.getSubString(","))

Solution 20 - Swift

the simples way that I use is :

String(Array(str)[2...4])

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAdrianView Question on Stackoverflow
Solution 1 - SwiftTamás SengelView Answer on Stackoverflow
Solution 2 - SwiftMohammad Sadegh PanadgooView Answer on Stackoverflow
Solution 3 - SwiftdimpiaxView Answer on Stackoverflow
Solution 4 - SwiftilnurView Answer on Stackoverflow
Solution 5 - SwiftThyerri MezzariView Answer on Stackoverflow
Solution 6 - SwiftAugust LinView Answer on Stackoverflow
Solution 7 - SwiftDenView Answer on Stackoverflow
Solution 8 - SwiftJohannesView Answer on Stackoverflow
Solution 9 - SwiftVladView Answer on Stackoverflow
Solution 10 - SwiftChhailengView Answer on Stackoverflow
Solution 11 - SwiftbyJeevanView Answer on Stackoverflow
Solution 12 - SwiftAshis LahaView Answer on Stackoverflow
Solution 13 - SwiftVincentView Answer on Stackoverflow
Solution 14 - SwiftAbizernView Answer on Stackoverflow
Solution 15 - SwiftJohnnyView Answer on Stackoverflow
Solution 16 - SwiftAnurag BhakuniView Answer on Stackoverflow
Solution 17 - Swiftjayesh kanzariyaView Answer on Stackoverflow
Solution 18 - Swiftuser1828845View Answer on Stackoverflow
Solution 19 - SwiftAnand VermaView Answer on Stackoverflow
Solution 20 - SwiftHamid ShahsavariView Answer on Stackoverflow