Swift: How to get substring from start to last index of character

前端 未结 22 732
感情败类
感情败类 2020-11-30 19:09

I want to learn the best/simplest way to turn a string into another string but with only a subset, starting at the beginning and going to the last index of a character.

相关标签:
22条回答
  • 2020-11-30 19:39

    Here's how I do it. You could do it the same way, or use this code for ideas.

    let s = "www.stackoverflow.com"
    s.substringWithRange(0..<s.lastIndexOf("."))
    

    Here are the extensions I use:

    import Foundation
    extension String {
    
      var length: Int {
        get {
          return countElements(self)
        }
      }
    
      func indexOf(target: String) -> Int {
        var range = self.rangeOfString(target)
        if let range = range {
          return distance(self.startIndex, range.startIndex)
        } else {
          return -1
        }
      }
    
      func indexOf(target: String, startIndex: Int) -> Int {
        var startRange = advance(self.startIndex, startIndex)        
        var range = self.rangeOfString(target, options: NSStringCompareOptions.LiteralSearch, range: Range<String.Index>(start: startRange, end: self.endIndex))
        if let range = range {
          return distance(self.startIndex, range.startIndex)
        } else {
          return -1
        }
      }
    
      func lastIndexOf(target: String) -> Int {
        var index = -1
        var stepIndex = self.indexOf(target)
        while stepIndex > -1 {
          index = stepIndex
          if stepIndex + target.length < self.length {
            stepIndex = indexOf(target, startIndex: stepIndex + target.length)
          } else {
            stepIndex = -1
          }
        }
        return index
      } 
    
      func substringWithRange(range:Range<Int>) -> String {
        let start = advance(self.startIndex, range.startIndex)
        let end = advance(self.startIndex, range.endIndex)
        return self.substringWithRange(start..<end)
      }
    
    }
    

    Credit albertbori / Common Swift String Extensions

    Generally I am a strong proponent of extensions, especially for needs like string manipulation, searching, and slicing.

    0 讨论(0)
  • 2020-11-30 19:40

    edit/update:

    In Swift 4 or later (Xcode 10.0+) you can use the new BidirectionalCollection method lastIndex(of:)

    func lastIndex(of element: Element) -> Int?
    

    let string = "www.stackoverflow.com"
    if let lastIndex = string.lastIndex(of: ".") {
        let subString = string[..<lastIndex]  // "www.stackoverflow"
    }
    
    0 讨论(0)
  • 2020-11-30 19:40

    Swift 3

    let string = "www.stackoverflow.com"
    let first3Characters = String(string.characters.prefix(3)) // www
    let lastCharacters = string.characters.dropFirst(4) // stackoverflow.com (it would be a collection)
    
    //or by index 
    let indexOfFouthCharacter = olNumber.index(olNumber.startIndex, offsetBy: 4)
    let first3Characters = olNumber.substring(to: indexOfFouthCharacter) // www
    let lastCharacters = olNumber.substring(from: indexOfFouthCharacter) // .stackoverflow.com
    

    Good article for understanding, why do we need this

    0 讨论(0)
  • 2020-11-30 19:41

    Swift 4:

    extension String {
    
        /// the length of the string
        var length: Int {
            return self.characters.count
        }
    
        /// Get substring, e.g. "ABCDE".substring(index: 2, length: 3) -> "CDE"
        ///
        /// - parameter index:  the start index
        /// - parameter length: the length of the substring
        ///
        /// - returns: the substring
        public func substring(index: Int, length: Int) -> String {
            if self.length <= index {
                return ""
            }
            let leftIndex = self.index(self.startIndex, offsetBy: index)
            if self.length <= index + length {
                return self.substring(from: leftIndex)
            }
            let rightIndex = self.index(self.endIndex, offsetBy: -(self.length - index - length))
            return self.substring(with: leftIndex..<rightIndex)
        }
    
        /// Get substring, e.g. -> "ABCDE".substring(left: 0, right: 2) -> "ABC"
        ///
        /// - parameter left:  the start index
        /// - parameter right: the end index
        ///
        /// - returns: the substring
        public func substring(left: Int, right: Int) -> String {
            if length <= left {
                return ""
            }
            let leftIndex = self.index(self.startIndex, offsetBy: left)
            if length <= right {
                return self.substring(from: leftIndex)
            }
            else {
                let rightIndex = self.index(self.endIndex, offsetBy: -self.length + right + 1)
                return self.substring(with: leftIndex..<rightIndex)
            }
        }
    }
    

    you can test it as follows:

        print("test: " + String("ABCDE".substring(index: 2, length: 3) == "CDE"))
        print("test: " + String("ABCDE".substring(index: 0, length: 3) == "ABC"))
        print("test: " + String("ABCDE".substring(index: 2, length: 1000) == "CDE"))
        print("test: " + String("ABCDE".substring(left: 0, right: 2) == "ABC"))
        print("test: " + String("ABCDE".substring(left: 1, right: 3) == "BCD"))
        print("test: " + String("ABCDE".substring(left: 3, right: 1000) == "DE"))
    

    Check https://gitlab.com/seriyvolk83/SwiftEx library. It contains these and other helpful methods.

    0 讨论(0)
  • 2020-11-30 19:41
    var url = "www.stackoverflow.com"
    let str = path.suffix(3)
    print(str) //low
    
    0 讨论(0)
  • 2020-11-30 19:42

    Do you want to get a substring of a string from start index to the last index of one of its characters? If so, you may choose one of the following Swift 2.0+ methods.

    Methods that require Foundation

    Get a substring that includes the last index of a character:

    import Foundation
    
    let string = "www.stackoverflow.com"
    if let rangeOfIndex = string.rangeOfCharacterFromSet(NSCharacterSet(charactersInString: "."), options: .BackwardsSearch) {
        print(string.substringToIndex(rangeOfIndex.endIndex))
    }
    
    // prints "www.stackoverflow."
    

    Get a substring that DOES NOT include the last index of a character:

    import Foundation
    
    let string = "www.stackoverflow.com"
    if let rangeOfIndex = string.rangeOfCharacterFromSet(NSCharacterSet(charactersInString: "."), options: .BackwardsSearch) {
        print(string.substringToIndex(rangeOfIndex.startIndex))
    }
    
    // prints "www.stackoverflow"
    

    If you need to repeat those operations, extending String can be a good solution:

    import Foundation
    
    extension String {
        func substringWithLastInstanceOf(character: Character) -> String? {
            if let rangeOfIndex = rangeOfCharacterFromSet(NSCharacterSet(charactersInString: String(character)), options: .BackwardsSearch) {
                return self.substringToIndex(rangeOfIndex.endIndex)
            }
            return nil
        }
        func substringWithoutLastInstanceOf(character: Character) -> String? {
            if let rangeOfIndex = rangeOfCharacterFromSet(NSCharacterSet(charactersInString: String(character)), options: .BackwardsSearch) {
                return self.substringToIndex(rangeOfIndex.startIndex)
            }
            return nil
        }
    }
    
    print("www.stackoverflow.com".substringWithLastInstanceOf("."))
    print("www.stackoverflow.com".substringWithoutLastInstanceOf("."))
    
    /*
    prints:
    Optional("www.stackoverflow.")
    Optional("www.stackoverflow")
    */
    

    Methods that DO NOT require Foundation

    Get a substring that includes the last index of a character:

    let string = "www.stackoverflow.com"
    if let reverseIndex = string.characters.reverse().indexOf(".") {
        print(string[string.startIndex ..< reverseIndex.base])
    }
    
    // prints "www.stackoverflow."
    

    Get a substring that DOES NOT include the last index of a character:

    let string = "www.stackoverflow.com"
    if let reverseIndex = string.characters.reverse().indexOf(".") {
        print(string[string.startIndex ..< reverseIndex.base.advancedBy(-1)])
    }
    
    // prints "www.stackoverflow"
    

    If you need to repeat those operations, extending String can be a good solution:

    extension String {
        func substringWithLastInstanceOf(character: Character) -> String? {
            if let reverseIndex = characters.reverse().indexOf(".") {
                return self[self.startIndex ..< reverseIndex.base]
            }
            return nil
        }
        func substringWithoutLastInstanceOf(character: Character) -> String? {
            if let reverseIndex = characters.reverse().indexOf(".") {
                return self[self.startIndex ..< reverseIndex.base.advancedBy(-1)]
            }
            return nil
        }
    }
    
    print("www.stackoverflow.com".substringWithLastInstanceOf("."))
    print("www.stackoverflow.com".substringWithoutLastInstanceOf("."))
    
    /*
    prints:
    Optional("www.stackoverflow.")
    Optional("www.stackoverflow")
    */
    
    0 讨论(0)
提交回复
热议问题