Swift: Cara mendapatkan substring dari awal hingga indeks karakter terakhir

110

Saya ingin mempelajari cara terbaik / paling sederhana untuk mengubah string menjadi string lain tetapi hanya dengan subset, dimulai dari awal dan menuju ke indeks terakhir karakter.

Misalnya, ubah "www.stackoverflow.com" menjadi "www.stackoverflow". Cuplikan kode apa yang akan melakukannya, dan menjadi yang paling cepat? (Saya harap ini tidak menimbulkan perdebatan, tetapi saya tidak dapat menemukan pelajaran yang baik tentang cara menangani substring di Swift.

Jason Hocker
sumber

Jawaban:

202

Hanya mengakses mundur

Cara terbaik adalah menggunakan substringToIndexgabungan endIndexproperti dan advancefungsi global.

var string1 = "www.stackoverflow.com"

var index1 = advance(string1.endIndex, -4)

var substring1 = string1.substringToIndex(index1)

Mencari senar dimulai dari belakang

Gunakan rangeOfStringdan setel optionske.BackwardsSearch

var string2 = "www.stackoverflow.com"

var index2 = string2.rangeOfString(".", options: .BackwardsSearch)?.startIndex

var substring2 = string2.substringToIndex(index2!)

Tanpa ekstensi, Swift idiomatik murni

Swift 2.0

advancesekarang menjadi bagian dari Indexdan disebut advancedBy. Anda melakukannya seperti:

var string1 = "www.stackoverflow.com"

var index1 = string1.endIndex.advancedBy(-4)

var substring1 = string1.substringToIndex(index1)

Swift 3.0.0

Anda tidak dapat memanggil advancedBypada Stringkarena memiliki unsur ukuran variabel. Anda harus menggunakan index(_, offsetBy:).

var string1 = "www.stackoverflow.com"

var index1 = string1.index(string1.endIndex, offsetBy: -4)

var substring1 = string1.substring(to: index1)

Banyak hal telah diubah namanya. Kasus-kasus tersebut ditulis dalam camelCase, startIndexmenjadi lowerBound.

var string2 = "www.stackoverflow.com"

var index2 = string2.range(of: ".", options: .backwards)?.lowerBound

var substring2 = string2.substring(to: index2!)

Juga, saya tidak akan merekomendasikan buka paksa index2. Anda dapat menggunakan penjilidan opsional atau map. Secara pribadi, saya lebih suka menggunakan map:

var substring3 = index2.map(string2.substring(to:))

Cepat 4

Versi Swift 3 masih valid tetapi sekarang Anda sekarang dapat menggunakan langganan dengan rentang indeks:

let string1 = "www.stackoverflow.com"

let index1 = string1.index(string1.endIndex, offsetBy: -4)

let substring1 = string1[..<index1]

Pendekatan kedua tetap tidak berubah:

let string2 = "www.stackoverflow.com"

let index2 = string2.range(of: ".", options: .backwards)?.lowerBound

let substring3 = index2.map(string2.substring(to:))
fpg1503
sumber
1
Terima kasih @ fpg1503. Ini adalah jenis jawaban yang ingin saya temukan. Jawaban lain mengajari saya atau mengingatkan saya tentang fitur-fitur dalam bahasa tersebut, tetapi ini adalah cara yang akan saya gunakan untuk menyelesaikan masalah saya.
Jason Hocker
1
Menggunakan Swift 2.0, string1.endIndex.advancedBy(-4)berfungsi untuk saya alih-alihadvance
Alex Koshy
92
Apakah benar-benar tidak ada cara untuk melakukan ini secara sederhana?
devios1
12
@viviii semuanya benar. Saya bersyukur untuk Swift dibandingkan dengan Objective-C, tetapi IMHO kekhawatiran yang mengarah pada kode yang sangat canggung ini tidak relevan untuk 99% kode dan pembuat kode di luar sana. Lebih buruk lagi, kami sendiri akan menulis ekstensi kenyamanan yang buruk. Jika pengembang reguler tidak dapat memahami masalah tingkat yang lebih tinggi ini, mereka PALING TIDAK mampu menulis API ad-hoc untuk menangani masalah pejalan kaki yang kami gunakan untuk membuat perangkat lunak. Kecenderungan pindah agama ke NSStringjelas juga buruk, karena akhirnya kita semua ingin lepas dari kelas Foundation (legacy). Jadi .... lebih gembar-gembor!
Dan Rosenstark
2
Di Swift 4, Anda bisa melakukannya string1[..<index1]. Tidak perlu string1.startIndex.
BauerMusic
26

Swift 3, XCode 8

func lastIndexOfCharacter(_ c: Character) -> Int? {
    return range(of: String(c), options: .backwards)?.lowerBound.encodedOffset
}

Sejak advancedBy(Int)hilang sejak Stringmetode penggunaan Swift 3 index(String.Index, Int). Lihat Stringekstensi ini dengan substring dan teman-teman:

public extension String {

    //right is the first encountered string after left
    func between(_ left: String, _ right: String) -> String? {
        guard let leftRange = range(of: left), let rightRange = range(of: right, options: .backwards)
        , leftRange.upperBound <= rightRange.lowerBound
            else { return nil }

        let sub = self.substring(from: leftRange.upperBound)
        let closestToLeftRange = sub.range(of: right)!
        return sub.substring(to: closestToLeftRange.lowerBound)
    }

    var length: Int {
        get {
            return self.characters.count
        }
    }

    func substring(to : Int) -> String {
        let toIndex = self.index(self.startIndex, offsetBy: to)
        return self.substring(to: toIndex)
    }

    func substring(from : Int) -> String {
        let fromIndex = self.index(self.startIndex, offsetBy: from)
        return self.substring(from: fromIndex)
    }

    func substring(_ r: Range<Int>) -> String {
        let fromIndex = self.index(self.startIndex, offsetBy: r.lowerBound)
        let toIndex = self.index(self.startIndex, offsetBy: r.upperBound)
        return self.substring(with: Range<String.Index>(uncheckedBounds: (lower: fromIndex, upper: toIndex)))
    }

    func character(_ at: Int) -> Character {
        return self[self.index(self.startIndex, offsetBy: at)]
    }

    func lastIndexOfCharacter(_ c: Character) -> Int? {
        guard let index = range(of: String(c), options: .backwards)?.lowerBound else
        { return nil }
        return distance(from: startIndex, to: index)
    }
}

Ekstensi yang DIPERBARUI untuk Swift 4

public extension String {

    //right is the first encountered string after left
    func between(_ left: String, _ right: String) -> String? {
        guard
            let leftRange = range(of: left), let rightRange = range(of: right, options: .backwards)
            , leftRange.upperBound <= rightRange.lowerBound
            else { return nil }

        let sub = self[leftRange.upperBound...]
        let closestToLeftRange = sub.range(of: right)!            
        return String(sub[..<closestToLeftRange.lowerBound])
    }

    var length: Int {
        get {
            return self.count
        }
    }

    func substring(to : Int) -> String {
        let toIndex = self.index(self.startIndex, offsetBy: to)
        return String(self[...toIndex])
    }

    func substring(from : Int) -> String {
        let fromIndex = self.index(self.startIndex, offsetBy: from)
        return String(self[fromIndex...])
    }

    func substring(_ r: Range<Int>) -> String {
        let fromIndex = self.index(self.startIndex, offsetBy: r.lowerBound)
        let toIndex = self.index(self.startIndex, offsetBy: r.upperBound)
        let indexRange = Range<String.Index>(uncheckedBounds: (lower: fromIndex, upper: toIndex))
        return String(self[indexRange])
    }

    func character(_ at: Int) -> Character {
        return self[self.index(self.startIndex, offsetBy: at)]
    }

    func lastIndexOfCharacter(_ c: Character) -> Int? {
        guard let index = range(of: String(c), options: .backwards)?.lowerBound else
        { return nil }
        return distance(from: startIndex, to: index)
    }
}

Pemakaian:

let text = "www.stackoverflow.com"
let at = text.character(3) // .
let range = text.substring(0..<3) // www
let from = text.substring(from: 4) // stackoverflow.com
let to = text.substring(to: 16) // www.stackoverflow
let between = text.between(".", ".") // stackoverflow
let substringToLastIndexOfChar = text.lastIndexOfCharacter(".") // 17

PS Sungguh aneh bahwa pengembang terpaksa berurusan dengan String.Indexbukannya polos Int. Mengapa kita harus peduli tentang Stringmekanika internal dan tidak hanya memiliki substring()metode sederhana ?

serg_zhd
sumber
Anda tidak boleh menggunakan encodedOffsetperiksa komentar ini dan cara yang benar untuk mencapai stackoverflow.com/questions/34540185/…
Leo Dabus
18

Saya akan melakukannya menggunakan subskrip ( s[start..<end]):

Cepat 3, 4, 5

let s = "www.stackoverflow.com"
let start = s.startIndex
let end = s.index(s.endIndex, offsetBy: -4)
let substring = s[start..<end] // www.stackoverflow
Marián Černý
sumber
11

edit / perbarui:

Di Swift 4 atau lebih baru (Xcode 10.0+) Anda dapat menggunakan metode BidirectionalCollection baru lastIndex (dari :)

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

let string = "www.stackoverflow.com"
if let lastIndex = string.lastIndex(of: ".") {
    let subString = string[..<lastIndex]  // "www.stackoverflow"
}
Leo Dabus
sumber
Ini adalah jawaban yang bagus, tetapi tampaknya dengan Swift 2, properti ini telah dipindahkan ke NSUrl. Mungkin ini membantu orang membaca ini di masa depan ...
chuky
8

Begini cara saya melakukannya. Anda dapat melakukannya dengan cara yang sama, atau menggunakan kode ini untuk mendapatkan ide.

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

Berikut ekstensi yang saya gunakan:

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)
  }

}

Kredit albertbori / Ekstensi String Swift Umum

Umumnya saya adalah pendukung kuat ekstensi, terutama untuk kebutuhan seperti manipulasi string, pencarian, dan pemotongan.

joelparkerhenderson
sumber
2
Saya pikir ini benar-benar sesuatu yang harus dilakukan Apple, untuk meningkatkan API String di Swift.
skyline75489
2
Mencari API ini. Apple Swift kekurangan banyak API dasar. Ini adalah bahasa yang sangat kompleks dan juga tidak lengkap. Swift itu omong kosong!
Loc
Ini adalah pustaka versi Swift 3 yang bercabang dan diperbarui ke versi Swift 3 yang Anda rujuk: github.com/iamjono/SwiftString
RenniePet
5

String memiliki fitur substring bawaan:

extension String : Sliceable {
    subscript (subRange: Range<String.Index>) -> String { get }
}

Jika yang Anda inginkan adalah "membuka indeks pertama karakter", Anda bisa mendapatkan substring menggunakan find()fungsi bawaan :

var str = "www.stackexchange.com"
str[str.startIndex ..< find(str, ".")!] // -> "www"

Untuk menemukan indeks terakhir , kita dapat menerapkan findLast().

/// Returns the last index where `value` appears in `domain` or `nil` if
/// `value` is not found.
///
/// Complexity: O(\ `countElements(domain)`\ )
func findLast<C: CollectionType where C.Generator.Element: Equatable>(domain: C, value: C.Generator.Element) -> C.Index? {
    var last:C.Index? = nil
    for i in domain.startIndex..<domain.endIndex {
        if domain[i] == value {
            last = i
        }
    }
    return last
}

let str = "www.stackexchange.com"
let substring = map(findLast(str, ".")) { str[str.startIndex ..< $0] } // as String?
// if "." is found, substring has some, otherwise `nil`

DITAMBAHKAN:

Mungkin, BidirectionalIndexTypeversi khusus findLastlebih cepat:

func findLast<C: CollectionType where C.Generator.Element: Equatable, C.Index: BidirectionalIndexType>(domain: C, value: C.Generator.Element) -> C.Index? {
    for i in lazy(domain.startIndex ..< domain.endIndex).reverse() {
        if domain[i] == value {
            return i
        }
    }
    return nil
}
rintaro
sumber
Subskrip untuk String sepertinya tidak tersedia di Swift 2.0, apakah Anda tahu penggantinya?
Cory
Apakah Anda tahu bagaimana cara membatasi Indeks ke BidirectionalIndexType di Swift 4 atau yang lebih baru?
Leo Dabus
5

Anda dapat menggunakan ekstensi ini:

Swift 2.3.0

 extension String
    {
        func substringFromIndex(index: Int) -> String
        {
            if (index < 0 || index > self.characters.count)
            {
                print("index \(index) out of bounds")
                return ""
            }
            return self.substringFromIndex(self.startIndex.advancedBy(index))
        }

        func substringToIndex(index: Int) -> String
        {
            if (index < 0 || index > self.characters.count)
            {
                print("index \(index) out of bounds")
                return ""
            }
            return self.substringToIndex(self.startIndex.advancedBy(index))
        }

        func substringWithRange(start: Int, end: Int) -> String
        {
            if (start < 0 || start > self.characters.count)
            {
                print("start index \(start) out of bounds")
                return ""
            }
            else if end < 0 || end > self.characters.count
            {
                print("end index \(end) out of bounds")
                return ""
            }
            let range = Range(start: self.startIndex.advancedBy(start), end: self.startIndex.advancedBy(end))
            return self.substringWithRange(range)
        }

        func substringWithRange(start: Int, location: Int) -> String
        {
            if (start < 0 || start > self.characters.count)
            {
                print("start index \(start) out of bounds")
                return ""
            }
            else if location < 0 || start + location > self.characters.count
            {
                print("end index \(start + location) out of bounds")
                return ""
            }
            let range = Range(start: self.startIndex.advancedBy(start), end: self.startIndex.advancedBy(start + location))
            return self.substringWithRange(range)
        }
    }

Cepat 3

extension String
{   
    func substring(from index: Int) -> String
    {
        if (index < 0 || index > self.characters.count)
        {
            print("index \(index) out of bounds")
            return ""
        }
        return self.substring(from: self.characters.index(self.startIndex, offsetBy: index))
    }

    func substring(to index: Int) -> String
    {
        if (index < 0 || index > self.characters.count)
        {
            print("index \(index) out of bounds")
            return ""
        }
        return self.substring(to: self.characters.index(self.startIndex, offsetBy: index))
    }

    func substring(start: Int, end: Int) -> String
    {
        if (start < 0 || start > self.characters.count)
        {
            print("start index \(start) out of bounds")
            return ""
        }
        else if end < 0 || end > self.characters.count
        {
            print("end index \(end) out of bounds")
            return ""
        }
        let startIndex = self.characters.index(self.startIndex, offsetBy: start)
        let endIndex = self.characters.index(self.startIndex, offsetBy: end)
        let range = startIndex..<endIndex

        return self.substring(with: range)
    }

    func substring(start: Int, location: Int) -> String
    {
        if (start < 0 || start > self.characters.count)
        {
            print("start index \(start) out of bounds")
            return ""
        }
        else if location < 0 || start + location > self.characters.count
        {
            print("end index \(start + location) out of bounds")
            return ""
        }
        let startIndex = self.characters.index(self.startIndex, offsetBy: start)
        let endIndex = self.characters.index(self.startIndex, offsetBy: start + location)
        let range = startIndex..<endIndex

        return self.substring(with: range)
    }
}

Pemakaian:

let string = "www.stackoverflow.com"        
let substring = string.substringToIndex(string.characters.count-4)
ChikabuZ
sumber
5

Cepat 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)
        }
    }
}

Anda bisa mengujinya sebagai berikut:

    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"))

Periksa https://gitlab.com/seriyvolk83/SwiftEx library. Ini berisi ini dan metode bermanfaat lainnya.

Alexander Volkov
sumber
4

Apakah Anda ingin mendapatkan substring dari sebuah string dari indeks awal hingga indeks terakhir dari salah satu karakternya? Jika demikian, Anda dapat memilih salah satu dari metode Swift 2.0+ berikut.

Metode yang membutuhkan Foundation

Dapatkan substring yang menyertakan indeks terakhir dari sebuah karakter:

import Foundation

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

// prints "www.stackoverflow."

Dapatkan substring yang TIDAK menyertakan indeks terakhir dari sebuah karakter:

import Foundation

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

// prints "www.stackoverflow"

Jika Anda perlu mengulangi operasi tersebut, memperluas Stringbisa menjadi solusi yang baik:

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")
*/

Metode yang TIDAK diperlukan Foundation

Dapatkan substring yang menyertakan indeks terakhir dari sebuah karakter:

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

// prints "www.stackoverflow."

Dapatkan substring yang TIDAK menyertakan indeks terakhir dari sebuah karakter:

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

// prints "www.stackoverflow"

Jika Anda perlu mengulangi operasi tersebut, memperluas Stringbisa menjadi solusi yang baik:

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")
*/
Imanou Petit
sumber
4

Berikut cara mudah dan singkat untuk mendapatkan substring jika Anda mengetahui indeksnya:

let s = "www.stackoverflow.com"
let result = String(s.characters.prefix(17)) // "www.stackoverflow"

Itu tidak akan merusak aplikasi jika indeks Anda melebihi panjang string:

let s = "short"
let result = String(s.characters.prefix(17)) // "short"

Kedua contoh sudah siap untuk Swift 3 .

Andrey Gordeev
sumber
4

Satu hal yang menambah suara gemerincing adalah pengulangan stringVar:

stringVar [ stringVar .index ( stringVar .startIndex, offsetBy: ...)

Di Swift 4

Perpanjangan dapat mengurangi beberapa di antaranya:

extension String {

    func index(at: Int) -> String.Index {
        return self.index(self.startIndex, offsetBy: at)
    }
}

Kemudian, penggunaan:

let string = "abcde"

let to = string[..<string.index(at: 3)] // abc
let from = string[string.index(at: 3)...] // de

Perlu dicatat bahwa todan fromadalah tipe Substring(atau String.SubSequance). Mereka tidak mengalokasikan string baru dan lebih efisien untuk pemrosesan.

Untuk mendapatkan kembali suatu Stringjenis, Substringperlu dicor kembali ke String:

let backToString = String(from)

Di sinilah string akhirnya dialokasikan.

bauerMusic
sumber
3
func substr(myString: String, start: Int, clen: Int)->String

{
  var index2 = string1.startIndex.advancedBy(start)
  var substring2 = string1.substringFromIndex(index2)
  var index1 = substring2.startIndex.advancedBy(clen)
  var substring1 = substring2.substringToIndex(index1)

  return substring1   
}

substr(string1, start: 3, clen: 5)
Profesor Oak
sumber
3

Cepat 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

Artikel yang bagus untuk pemahaman, mengapa kita membutuhkan ini

Nik Kov
sumber
2

Saya telah memperpanjang String dengan dua metode substring. Anda dapat memanggil substring dengan rentang dari / ke atau dari / panjang seperti:

var bcd = "abcdef".substring(1,to:3)
var cde = "abcdef".substring(2,to:-2)
var cde = "abcdef".substring(2,length:3)

extension String {
  public func substring(from:Int = 0, var to:Int = -1) -> String {
    if to < 0 {
        to = self.length + to
    }
    return self.substringWithRange(Range<String.Index>(
        start:self.startIndex.advancedBy(from),
        end:self.startIndex.advancedBy(to+1)))
  }
  public func substring(from:Int = 0, length:Int) -> String {
    return self.substringWithRange(Range<String.Index>(
        start:self.startIndex.advancedBy(from),
        end:self.startIndex.advancedBy(from+length)))
  }
}
andrewz
sumber
self.length tidak tersedia lagi. Anda perlu menambahkan ini di ekstensi (Andrewz, harap perbarui kode; saya tidak ingin mengirim jawaban lain): public func length () -> Int {return self.lengthOfBytesUsingEncoding (NSUTF16StringEncoding)}
philippe
1

Swift 2.0 Kode di bawah ini diuji pada XCode 7.2. Silakan lihat tangkapan layar terlampir di bagian bawah

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var mainText = "http://stackoverflow.com"

        var range = Range(start: mainText.startIndex.advancedBy(7), end: mainText.startIndex.advancedBy(24))
        var subText = mainText.substringWithRange(range)


        //OR Else use below for LAST INDEX

        range = Range(start: mainText.startIndex.advancedBy(7), end: mainText.endIndex)
        subText = mainText.substringWithRange(range)
    }
}
Chamath Jeevan
sumber
1

Di Swift 5

Kita membutuhkan String.Indexbukan nilai Int sederhana untuk mewakili Indeks.

Juga ingat, ketika kita mencoba untuk mendapatkan subString dari Swift String(tipe nilai), kita sebenarnya harus mengulang dengan Sequenceprotokol, yang mengembalikan String.SubSequencetipe daripadaString tipe.

Untuk kembali Stringdari String.SubSequence, gunakanString(subString)

Contoh Seperti Di Bawah Ini:

    let string = "https://stackoverflow.com"
    let firstIndex = String.Index(utf16Offset: 0, in: string)
    let lastIndex = String.Index(utf16Offset: 6, in: string)
    let subString = String(string[firstIndex...lastIndex])
macpandit
sumber
0

Untuk Swift 2.0 , seperti ini:

var string1 = "www.stackoverflow.com"
var index1 = string1.endIndex.advancedBy(-4)
var substring1 = string1.substringToIndex(index1)
mike.tihonchik
sumber
Mungkin mereka telah mengubahnya, tetapi ini adalah 'advancedBy' (perhatikan 'd' di akhir 'advanced')
Wedge Martin
0

Saya telah memodifikasi posting andrewz agar kompatibel dengan Swift 2.0 (dan mungkin Swift 3.0). Menurut pendapat saya, ekstensi ini lebih mudah dipahami dan mirip dengan yang tersedia dalam bahasa lain (seperti PHP).

extension String {

    func length() -> Int {
        return self.lengthOfBytesUsingEncoding(NSUTF16StringEncoding)
    }
    func substring(from:Int = 0, to:Int = -1) -> String {
       var nto=to
        if nto < 0 {
            nto = self.length() + nto
        }
        return self.substringWithRange(Range<String.Index>(
           start:self.startIndex.advancedBy(from),
           end:self.startIndex.advancedBy(nto+1)))
    }
    func substring(from:Int = 0, length:Int) -> String {
        return self.substringWithRange(Range<String.Index>(
            start:self.startIndex.advancedBy(from),
            end:self.startIndex.advancedBy(from+length)))
    }
}
philippe
sumber
0

Saya juga membuat ekstensi String sederhana untuk Swift 4:

extension String {
    func subStr(s: Int, l: Int) -> String { //s=start, l=lenth
        let r = Range(NSRange(location: s, length: l))!
        let fromIndex = self.index(self.startIndex, offsetBy: r.lowerBound)
        let toIndex = self.index(self.startIndex, offsetBy: r.upperBound)
        let indexRange = Range<String.Index>(uncheckedBounds: (lower: fromIndex, upper: toIndex))

        return String(self[indexRange])
     }
}

Jadi Anda bisa dengan mudah menyebutnya seperti ini:

"Hallo world".subStr(s: 1, l: 3) //prints --> "all"
Marco Weber
sumber
0

Coba Int-basedsolusi ini :

extension String {
    // start and end is included
    func intBasedSubstring(_ start: Int, _ end: Int) -> String {
        let endOffset: Int = -(count - end - 1)
        let startIdx = self.index(startIndex, offsetBy: start)
        let endIdx = self.index(endIndex, offsetBy: endOffset)
        return String(self[startIdx..<endIdx])
    }
}

Catatan: Ini hanya latihan. Itu tidak memeriksa batas. Modifikasi sesuai kebutuhan Anda.

steveluoxin.dll
sumber
-1

Berikut ini cara sederhana untuk mendapatkan substring di Swift

import UIKit

var str = "Hello, playground" 
var res = NSString(string: str)
print(res.substring(from: 4))
print(res.substring(to: 10))
ZagorTeNej
sumber
OP menanyakan "Cara mendapatkan substring dari awal hingga indeks karakter terakhir" bukan cara mendapatkan substring menggunakan nilai hardcode yang telah ditentukan sebelumnya.
Eric Aya
Ini adalah contoh asli: ubah "www.stackoverflow.com" menjadi "www.stackoverflow". Jika Anda menginginkan substring dari awal sampai akhir maka tidak ada yang bisa dilakukan yaitu hasilnya adalah input string apa adanya. Mohon kembalikan kegunaan jawaban di atas.
ZagorTeNej