Come funziona la sottostringa String in Swift


354

Ho aggiornato parte del mio vecchio codice e delle risposte con Swift 3 ma quando sono arrivato a Swift Strings e all'indicizzazione con sottostringhe le cose sono diventate confuse.

In particolare stavo provando quanto segue:

let str = "Hello, playground"
let prefixRange = str.startIndex..<str.startIndex.advancedBy(5)
let prefix = str.substringWithRange(prefixRange)

dove la seconda riga mi stava dando il seguente errore

Il valore di tipo 'String' non ha membri 'substringWithRange'

Vedo che ora Stringha i seguenti metodi:

str.substring(to: String.Index)
str.substring(from: String.Index)
str.substring(with: Range<String.Index>)

All'inizio mi stavano confondendo, quindi ho iniziato a giocare su indice e intervallo . Questa è una domanda di risposta e una risposta per la sottostringa. Sto aggiungendo una risposta qui sotto per mostrare come vengono utilizzati.


2
Per coloro che vogliono ottenere la sottostringa dalla stringa stackoverflow.com/q/32305891/468724
Inder Kumar Rathore,

o una stringa pedice o sottostringa stackoverflow.com/questions/24092884/...
Leo Dabus

Risposte:


832

inserisci qui la descrizione dell'immagine

Tutti gli esempi seguenti usano

var str = "Hello, playground"

Swift 4

Le stringhe hanno subito una revisione abbastanza grande in Swift 4. Quando ottieni subito una sottostringa da una stringa, ottieni un Substringtipo indietro piuttosto che a String. Perchè è questo? Le stringhe sono tipi di valore in Swift. Ciò significa che se si utilizza una stringa per crearne una nuova, è necessario copiarla. Questo è buono per la stabilità (nessun altro lo cambierà a tua insaputa) ma cattivo per l'efficienza.

Un sottostringa, d'altra parte, è un riferimento alla stringa originale da cui proviene. Ecco un'immagine dalla documentazione che lo illustra.

Non è necessaria alcuna copia, quindi è molto più efficiente da usare. Tuttavia, immagina di avere un sottostringa di dieci caratteri da una stringa di un milione di caratteri. Poiché il sottostringa fa riferimento alla stringa, il sistema dovrebbe trattenere l'intera stringa fintanto che la sottostringa è in giro. Pertanto, ogni volta che hai finito di manipolare il tuo sottostringa, convertilo in una stringa.

let myString = String(mySubstring)

Questo copierà solo la sottostringa e la memoria contenente la vecchia stringa può essere recuperata . I sottostringhe (come tipo) devono essere di breve durata.

Un altro grande miglioramento in Swift 4 è che le stringhe sono raccolte (di nuovo). Ciò significa che qualunque cosa tu possa fare in una Collezione, puoi farlo in una String (usa gli script, scorre i caratteri, filtra, ecc.).

I seguenti esempi mostrano come ottenere una sottostringa in Swift.

Ottenere sottostringhe

È possibile ottenere una stringa da una stringa utilizzando pedici o un certo numero di altri metodi (ad esempio, prefix, suffix, split). Tuttavia, è ancora necessario utilizzare String.Indexe non un Intindice per l'intervallo. (Vedi la mia altra risposta se hai bisogno di aiuto con quello.)

Inizio di una stringa

È possibile utilizzare un pedice (notare l'intervallo unilaterale di Swift 4):

let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str[..<index] // Hello

oppure prefix:

let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str.prefix(upTo: index) // Hello

o ancora più semplice:

let mySubstring = str.prefix(5) // Hello

Fine di una stringa

Usando i pedici:

let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str[index...] // playground

oppure suffix:

let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str.suffix(from: index) // playground

o ancora più semplice:

let mySubstring = str.suffix(10) // playground

Si noti che quando si utilizzava l' suffix(from: index)ho dovuto contare indietro alla fine utilizzando -10. Ciò non è necessario quando si utilizza semplicemente suffix(x), che accetta solo gli ultimi xcaratteri di una stringa.

Intervallo in una stringa

Anche in questo caso utilizziamo semplicemente i pedici qui.

let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end

let mySubstring = str[range]  // play

Conversione SubstringinString

Non dimenticare, quando sei pronto per salvare la sottostringa, dovresti convertirla in un Stringmodo che la memoria della vecchia stringa possa essere ripulita.

let myString = String(mySubstring)

L'utilizzo di un Intestensione di indice?

Sono titubante nell'utilizzare Intun'estensione dell'indice basata dopo aver letto l'articolo Strings in Swift 3 di Airspeed Velocity e Ole Begemann. Sebbene in Swift 4, le stringhe siano raccolte, il team Swift non ha intenzionalmente utilizzato gli Intindici. È ancora String.Index. Ciò ha a che fare con i personaggi Swift composti da un numero variabile di punti di codice Unicode. L'indice effettivo deve essere calcolato in modo univoco per ogni stringa.

Devo dire che spero che il team Swift trovi un modo per sottrarsi String.Indexal futuro. Ma fino a loro scelgo di usare la loro API. Mi aiuta a ricordare che le manipolazioni di stringhe non sono solo semplici Intricerche di indice.


9
Grazie per la descrizione. Meritevoli aggiornamenti. Apple ha complicato questo aspetto. Il sottostring dovrebbe essere facile come string.substring [da ... a].
Teddy,

Davvero una buona spiegazione. tranne una piccola cosa garbage collected;-) Spero che le persone qui sappiano che non c'è raccolta di rifiuti in Swift.
Christian Anchor Dampf,

@ChristianAnchorDampf, Grazie per aver dedicato del tempo per commentare. Ho portato fuori la raccolta dei rifiuti. Come è la nuova formulazione?
Suragch il

Che risposta incredibile signore !!
davidev,

194

Sono davvero frustrato dal modello di accesso String di Swift: tutto deve essere un Index. Tutto quello che voglio è accedere all'i-esimo carattere della stringa usando Int, non l'indice maldestro e l'avanzamento (che succede con ogni versione principale). Quindi ho fatto un'estensione per String:

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

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

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

    func substring(with r: Range<Int>) -> String {
        let startIndex = index(from: r.lowerBound)
        let endIndex = index(from: r.upperBound)
        return String(self[startIndex..<endIndex])
    }
}

let str = "Hello, playground"
print(str.substring(from: 7))         // playground
print(str.substring(to: 5))           // Hello
print(str.substring(with: 7..<11))    // play

5
Gli indici sono molto utili perché un carattere può essere più di un byte. Provalet str = "🇨🇭🇩🇪🇺🇸Hello" print(str.substring(to: 2))
vadian

112
Sì, capisco che un carattere (ovvero cluster grapheme esteso ) può richiedere più byte. La mia frustrazione è il motivo per cui dobbiamo usare il metodo avanzato di avanzamento dell'indice per accedere ai caratteri di una stringa. Perché il team Swift non può semplicemente aggiungere alcuni sovraccarichi alla Core Library per sottrarla. Se scrivo str[5], desidero accedere al carattere all'indice 5, qualunque sia quel carattere o quanti byte ci vogliono. Swift non si occupa solo della produttività degli sviluppatori?
Codice diverso

6
@RenniePet Credo che Apple riconosca il problema e che i cambiamenti stiano arrivando. Secondo la pagina Swift Evolution su GitHub: "Swift 4 cerca di rendere le stringhe più potenti e più facili da usare, mantenendo la correttezza Unicode per impostazione predefinita". È vago ma manteniamo le nostre speranze
Code Different

3
@CodeDifferente perché apple non ha aggiunto l'accesso ai caratteri in pedice? In modo che la gente capisca che è una brutta cosa da fare. Fondamentalmente se lo faresti per i in 0..string.count usando gli script che sarebbero doppio loop, perché sotto l'indice del cappuccio deve passare attraverso ogni byte di stringa per scoprire qual è il carattere successivo. Se esegui il ciclo utilizzando l'indice, esegui l'iterazione della stringa una sola volta. A proposito, odio questo me stesso, ma questo è il ragionamento che sta dietro il pedice non essendo disponibile sulla stringa in breve tempo.
Raimundas Sakalauskas,

4
@RaimundasSakalauskas quell'argomento non vola da me. C # ha sia la correttezza Unicode che la sottoscrizione di numeri interi, il che è davvero conveniente. In Swift 1, Apple voleva che gli sviluppatori usassero countElement(str)per trovare la lunghezza. In Swift 3, Apple ha reso la stringa non conforme Sequencee ha costretto tutti a usarla str.characters. Questi ragazzi non hanno timore di fare cambiamenti. La loro testardaggine sulla sottoscrizione di numeri interi è davvero difficile da capire
Codice diverso il

103

Estensione Swift 5:

extension String {
    subscript(_ range: CountableRange<Int>) -> String {
        let start = index(startIndex, offsetBy: max(0, range.lowerBound))
        let end = index(start, offsetBy: min(self.count - range.lowerBound, 
                                             range.upperBound - range.lowerBound))
        return String(self[start..<end])
    }

    subscript(_ range: CountablePartialRangeFrom<Int>) -> String {
        let start = index(startIndex, offsetBy: max(0, range.lowerBound))
         return String(self[start...])
    }
}

Uso:

let s = "hello"
s[0..<3] // "hel"
s[3...]  // "lo"

O unicode:

let s = "😎🤣😋"
s[0..<1] // "😎"

2
Molto meglio, grazie per aver pubblicato questa estensione! Penso che proveniente da Python, Swift sia molto più difficile del necessario per abituarsi. Sembra che per le persone che vanno nella direzione opposta dall'obiettivo C a Swift ci sia una conferma più positiva.
user3064009

1
@Leon L'ho appena rimosso. Prima della 4.1, countera disponibile solo ilself.characters
Lou Zell

1
Ci sono dei gotcha a cui prestare attenzione con questa particolare estensione? Perché Apple non ha fatto qualcosa del genere?
Andz,

1
@Andz è molto inefficiente. Inizia dall'inizio della stringa - due volte - e deve analizzare ogni carattere da lì a "intervallo" - due volte.
Kareman,

3
Dovrai anche aggiungere un'estensione che richiede unaCountableClosedRange<Int> se desideri scrivere ad es s[0...2].
Chris Frederick,

24

Swift 4 e 5:

extension String {
  subscript(_ i: Int) -> String {
    let idx1 = index(startIndex, offsetBy: i)
    let idx2 = index(idx1, offsetBy: 1)
    return String(self[idx1..<idx2])
  }

  subscript (r: Range<Int>) -> String {
    let start = index(startIndex, offsetBy: r.lowerBound)
    let end = index(startIndex, offsetBy: r.upperBound)
    return String(self[start ..< end])
  }

  subscript (r: CountableClosedRange<Int>) -> String {
    let startIndex =  self.index(self.startIndex, offsetBy: r.lowerBound)
    let endIndex = self.index(startIndex, offsetBy: r.upperBound - r.lowerBound)
    return String(self[startIndex...endIndex])
  }
}

Come usarlo:

"abcde" [0] -> "a"

"abcde" [0 ... 2] -> "abc"

"abcde" [2 .. <4] -> "cd"


20

Swift 4

In rapido 4 si Stringconforma a Collection. Invece di substring, ora dovremmo usare un subscript.Quindi, se si vuole tagliare fuori solo la parola "play"da "Hello, playground", si potrebbe fare in questo modo:

var str = "Hello, playground"
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let result = str[start..<end] // The result is of type Substring

È interessante sapere che farlo ti darà Substringinvece di aString . Questo è veloce ed efficiente in quanto Substringcondivide la sua memoria con la stringa originale. Tuttavia, condividere la memoria in questo modo può anche portare facilmente a perdite di memoria.

Questo è il motivo per cui dovresti copiare il risultato in una nuova stringa, una volta che vuoi ripulire la stringa originale. Puoi farlo usando il normale costruttore:

let newString = String(result)

Puoi trovare ulteriori informazioni sulla nuova Substringclasse nella [documentazione Apple].1

Quindi, se ad esempio ottieni a Rangecome risultato di un NSRegularExpression, puoi usare la seguente estensione:

extension String {

    subscript(_ range: NSRange) -> String {
        let start = self.index(self.startIndex, offsetBy: range.lowerBound)
        let end = self.index(self.startIndex, offsetBy: range.upperBound)
        let subString = self[start..<end]
        return String(subString)
    }

}

Il codice si arresta in modo anomalo se range.upperBound è> lunghezza della stringa. Inoltre, un esempio di utilizzo sarebbe stato utile, dato che non avevo familiarità con gli script in Swift. Potresti includere qualcosa come datePartOnly = "2018-01-04-08: 00" [NSMakeRange (0, 10)]. A parte questo, bella risposta, +1 :).
dcp,

oggi è questa cosa strana: text[Range( nsRange , in: text)!]
Fattie

10

Ecco una funzione che restituisce la sottostringa di una determinata sottostringa quando vengono forniti gli indici di inizio e fine. Per un riferimento completo è possibile visitare i collegamenti indicati di seguito.

func substring(string: String, fromIndex: Int, toIndex: Int) -> String? {
    if fromIndex < toIndex && toIndex < string.count /*use string.characters.count for swift3*/{
        let startIndex = string.index(string.startIndex, offsetBy: fromIndex)
        let endIndex = string.index(string.startIndex, offsetBy: toIndex)
        return String(string[startIndex..<endIndex])
    }else{
        return nil
    }
}

Ecco un link al post sul blog che ho creato per gestire rapidamente la manipolazione delle stringhe. Manipolazione delle stringhe in swift (copre anche swift 4)

Oppure puoi vedere questo succo su github


9

Ho avuto la stessa reazione iniziale. Anch'io ero frustrato dal modo in cui la sintassi e gli oggetti cambiano così drasticamente in ogni versione principale.

Tuttavia, per esperienza mi sono reso conto che alla fine ho sempre sofferto le conseguenze del tentativo di combattere il "cambiamento" come affrontare i personaggi multi-byte, il che è inevitabile se stai guardando un pubblico globale.

Così ho deciso di riconoscere e rispettare gli sforzi esercitati dagli ingegneri Apple e di fare la mia parte capendo la loro mentalità quando hanno escogitato questo approccio "orribile".

Invece di creare estensioni che sono solo una soluzione alternativa per semplificarti la vita (non sto dicendo che sono sbagliate o costose), perché non capire come ora le stringhe sono progettate per funzionare.

Ad esempio, avevo questo codice che funzionava su Swift 2.2:

let rString = cString.substringToIndex(2)
let gString = (cString.substringFromIndex(2) as NSString).substringToIndex(2)
let bString = (cString.substringFromIndex(4) as NSString).substringToIndex(2)

e dopo aver smesso di provare a far funzionare lo stesso approccio, ad esempio usando Substrings, ho finalmente capito il concetto di trattare le stringhe come una raccolta bidirezionale per la quale ho finito con questa versione dello stesso codice:

let rString = String(cString.characters.prefix(2))
cString = String(cString.characters.dropFirst(2))
let gString = String(cString.characters.prefix(2))
cString = String(cString.characters.dropFirst(2))
let bString = String(cString.characters.prefix(2))

Spero che questo contribuisca ...


1
Bene, affrontare un problema complesso non significa che la soluzione potrebbe essere elegante. Ancora una volta, capisco anche il problema, ma l'intera classe String e affrontarla è semplicemente orribile.
inexcitus,

5

Stessa frustrazione, questo non dovrebbe essere così difficile ...

Ho compilato questo esempio per ottenere posizioni per sottostringhe da testo più grande:

//
// Play with finding substrings returning an array of the non-unique words and positions in text
//
//

import UIKit

let Bigstring = "Why is it so hard to find substrings in Swift3"
let searchStrs : Array<String>? = ["Why", "substrings", "Swift3"]

FindSubString(inputStr: Bigstring, subStrings: searchStrs)


func FindSubString(inputStr : String, subStrings: Array<String>?) ->    Array<(String, Int, Int)> {
    var resultArray : Array<(String, Int, Int)> = []
    for i: Int in 0...(subStrings?.count)!-1 {
        if inputStr.contains((subStrings?[i])!) {
            let range: Range<String.Index> = inputStr.range(of: subStrings![i])!
            let lPos = inputStr.distance(from: inputStr.startIndex, to: range.lowerBound)
            let uPos = inputStr.distance(from: inputStr.startIndex, to: range.upperBound)
            let element = ((subStrings?[i])! as String, lPos, uPos)
            resultArray.append(element)
        }
    }
    for words in resultArray {
        print(words)
    }
    return resultArray
}

Returns ("Why", 0, 3) ("substrings", 26, 36) ("Swift3", 40, 46)


3
Questo è un po 'di codice, ma in realtà non spiega come funzionano l'indicizzazione delle stringhe e le sottostringhe in swift3.
Robert,

5

Sono nuovo in Swift 3, ma guardando la Stringsintassi (indice) per analogia penso che l'indice sia come un "puntatore" vincolato alla stringa e Int può aiutare come oggetto indipendente. Usando la sintassi base + offset, possiamo ottenere l'i-esimo carattere dalla stringa con il codice seguente:

let s = "abcdefghi"
let i = 2
print (s[s.index(s.startIndex, offsetBy:i)])
// print c

Per un intervallo di caratteri (indici) dalla stringa utilizzando la sintassi String (intervallo), possiamo ottenere dall'i-esimo all'ottavo carattere con il codice seguente:

let f = 6
print (s[s.index(s.startIndex, offsetBy:i )..<s.index(s.startIndex, offsetBy:f+1 )])
//print cdefg

Per una sottostringa (intervallo) da una stringa utilizzando String.substring (intervallo) possiamo ottenere la sottostringa utilizzando il codice seguente:

print (s.substring (with:s.index(s.startIndex, offsetBy:i )..<s.index(s.startIndex, offsetBy:f+1 ) ) )
//print cdefg

Appunti:

  1. I-th e f-th iniziano con 0.

  2. Per f-th, uso offsetBY: f + 1, perché l'intervallo dell'abbonamento usa .. <(operatore semi-aperto), non includo la f-esima posizione.

  3. Ovviamente deve includere errori di convalida come indice non valido.


5

Swift 4+

extension String {
    func take(_ n: Int) -> String {
        guard n >= 0 else {
            fatalError("n should never negative")
        }
        let index = self.index(self.startIndex, offsetBy: min(n, self.count))
        return String(self[..<index])
    }
}

Restituisce una sottosequenza dei primi n caratteri o dell'intera stringa se la stringa è più corta. (ispirato a: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/take.html )

Esempio:

let text = "Hello, World!"
let substring = text.take(5) //Hello

4

Sono un pensiero abbastanza meccanico. Ecco le basi ...

Swift 4 Swift 5

  let t = "abracadabra"

  let start1 = t.index(t.startIndex, offsetBy:0)
  let   end1 = t.index(t.endIndex, offsetBy:-5)
  let start2 = t.index(t.endIndex, offsetBy:-5)
  let   end2 = t.index(t.endIndex, offsetBy:0)

  let t2 = t[start1 ..< end1]
  let t3 = t[start2 ..< end2]                

  //or a shorter form 

  let t4 = t[..<end1]
  let t5 = t[start2...]

  print("\(t2) \(t3) \(t)")
  print("\(t4) \(t5) \(t)")

  // result:
  // abraca dabra abracadabra

Il risultato è una sottostringa, il che significa che fa parte della stringa originale. Per ottenere una stringa separata completa basta usare ad es

    String(t3)
    String(t4)

Questo è quello che uso:

    let mid = t.index(t.endIndex, offsetBy:-5)
    let firstHalf = t[..<mid]
    let secondHalf = t[mid...]

3

Swift 4

extension String {
    subscript(_ i: Int) -> String {
        let idx1 = index(startIndex, offsetBy: i)
        let idx2 = index(idx1, offsetBy: 1)
        return String(self[idx1..<idx2])
    }
}

let s = "hello"

s[0]    // h
s[1]    // e
s[2]    // l
s[3]    // l
s[4]    // o

2

Ho creato una semplice estensione per questo (Swift 3)

extension String {
    func substring(location: Int, length: Int) -> String? {
        guard characters.count >= location + length else { return nil }
        let start = index(startIndex, offsetBy: location)
        let end = index(startIndex, offsetBy: location + length)
        return substring(with: start..<end)
    }
}

2

Ecco un'implementazione più generica:

Questa tecnica utilizza ancora indexper rispettare gli standard di Swift e implica un personaggio completo.

extension String
{
    func subString <R> (_ range: R) -> String? where R : RangeExpression, String.Index == R.Bound
    {
        return String(self[range])
    }

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

Per sottostringa dal 3 ° carattere:

let item = "Fred looks funny"
item.subString(item.index(at: 2)...) // "ed looks funny"

Ho usato il cammello subStringper indicare che restituisce a Stringe non a Substring.


2

Partendo da quanto sopra, ho dovuto dividere una stringa in corrispondenza di un carattere non stampabile rilasciando il carattere non stampabile. Ho sviluppato due metodi:

var str = "abc\u{1A}12345sdf"
let range1: Range<String.Index> = str.range(of: "\u{1A}")!
let index1: Int = str.distance(from: str.startIndex, to: range1.lowerBound)
let start = str.index(str.startIndex, offsetBy: index1)
let end = str.index(str.endIndex, offsetBy: -0)
let result = str[start..<end] // The result is of type Substring
let firstStr = str[str.startIndex..<range1.lowerBound]

che ho messo insieme usando alcune delle risposte sopra.

Poiché una stringa è una raccolta, ho quindi fatto quanto segue:

var fString = String()
for (n,c) in str.enumerated(){

*if c == "\u{1A}" {
    print(fString);
    let lString = str.dropFirst(n + 1)
    print(lString)
    break
   }
 fString += String(c)
}*

Quale per me era più intuitivo. Qual è il migliore? Non ho modo di dirlo Entrambi lavorano con Swift 5


Grazie per la tua risposta. C'è qualcosa di diverso in Strings in Swift 5? Non ho ancora avuto il tempo di giocarci.
Suragch

Lo dicono, ma non ho avuto la possibilità di esaminarlo.
Jeremy Andrews,

1

Swift 4

"Sottostringa" ( https://developer.apple.com/documentation/swift/substring ):

let greeting = "Hi there! It's nice to meet you! 👋"
let endOfSentence = greeting.index(of: "!")!
let firstSentence = greeting[...endOfSentence]
// firstSentence == "Hi there!"

Esempio di estensione String:

private typealias HowDoYouLikeThatElonMusk = String
private extension HowDoYouLikeThatElonMusk {

    subscript(_ from: Character?, _ to: Character?, _ include: Bool) -> String? {
        if let _from: Character = from, let _to: Character = to {
            let dynamicSourceForEnd: String = (_from == _to ? String(self.reversed()) : self)
            guard let startOfSentence: String.Index = self.index(of: _from),
                let endOfSentence: String.Index = dynamicSourceForEnd.index(of: _to) else {
                return nil
            }

            let result: String = String(self[startOfSentence...endOfSentence])
            if include == false {
                guard result.count > 2 else {
                        return nil
                }
                return String(result[result.index(result.startIndex, offsetBy: 1)..<result.index(result.endIndex, offsetBy: -1)])
            }
            return result
        } else if let _from: Character = from {
            guard let startOfSentence: String.Index = self.index(of: _from) else {
                return nil
            }
            let result: String = String(self[startOfSentence...])
            if include == false {
                guard result.count > 1 else {
                    return nil
                }
                return String(result[result.index(result.startIndex, offsetBy: 1)...])
            }
            return result
        } else if let _to: Character = to {
            guard let endOfSentence: String.Index = self.index(of: _to) else {
                    return nil
            }
            let result: String = String(self[...endOfSentence])
            if include == false {
                guard result.count > 1 else {
                    return nil
                }
                return String(result[..<result.index(result.endIndex, offsetBy: -1)])
            }
            return result
        }
        return nil
    }
}

esempio di utilizzo dell'estensione String:

let source =                                   ">>>01234..56789<<<"
// include = true
var from =          source["3", nil, true]  //       "34..56789<<<"
var to =            source[nil, "6", true]  // ">>>01234..56"
var fromTo =        source["3", "6", true]  //       "34..56"
let notFound =      source["a", nil, true]  // nil
// include = false
from =              source["3", nil, false] //        "4..56789<<<"
to =                source[nil, "6", false] // ">>>01234..5"
fromTo =            source["3", "6", false] //        "4..5"
let outOfBounds =   source[".", ".", false] // nil

let str = "Hello, playground"
let hello = str[nil, ",", false] // "Hello"

-1

Swift 5
let desiredIndex: Int = 7 let substring = str[String.Index(encodedOffset: desiredIndex)...]
Questa variabile di sottostringa ti darà il risultato.
Semplicemente qui Int viene convertito in indice e quindi è possibile dividere le stringhe. A meno che non otterrai errori.


2
Questo è sbagliato. Un personaggio potrebbe essere costituito da uno o più byte. Funziona solo con testo ASCII.
Leo Dabus,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.