Ich konnte noch nicht herausfinden, wie man einen Teilstring von a String
in Swift erhält :
var str = “Hello, playground”
func test(str: String) -> String {
return str.substringWithRange( /* What goes here? */ )
}
test (str)
Ich kann in Swift keinen Bereich erstellen. Die automatische Vervollständigung auf dem Spielplatz ist nicht besonders hilfreich - dies schlägt vor:
return str.substringWithRange(aRange: Range<String.Index>)
Ich habe in der Swift Standard Reference Library nichts gefunden, was hilft. Hier war eine weitere wilde Vermutung:
return str.substringWithRange(Range(0, 1))
Und das:
let r:Range<String.Index> = Range<String.Index>(start: 0, end: 2)
return str.substringWithRange(r)
Ich habe andere Antworten gesehen ( Finden des Zeichenindex in Swift String ), die darauf hindeuten, dass die "alten" Methoden funktionieren sollten , da String
es sich um einen Brückentyp handelt NSString
, aber es ist nicht klar, wie - z. B. funktioniert dies auch nicht ( scheint keine gültige Syntax zu sein):
let x = str.substringWithRange(NSMakeRange(0, 3))
Gedanken?
Antworten:
Sie können die Methode substringWithRange verwenden. Es dauert einen Start und ein Ende von String.Index.
Verwenden Sie advancedBy (n), um den Start- und Endindex zu ändern.
Sie können die NSString-Methode auch weiterhin mit NSRange verwenden, müssen jedoch sicherstellen, dass Sie einen NSString wie folgt verwenden:
Hinweis: Wie bereits in JanX2 erwähnt, ist diese zweite Methode mit Unicode-Zeichenfolgen nicht sicher.
quelle
advance
bedeutet, dass wir den gesamten Weg durch eine möglicherweise lange Zeichenfolge durchlaufen müssen. Aber eine NSRange zu bilden und NSString explizit zu verwenden, ist gefährlich? Was ist übrig?Swift 2
Einfach
Swift 3
Swift 4
substring(to:)
undsubstring(from:)
sind veraltet inSwift 4
.quelle
HINWEIS: @airspeedswift macht einige sehr aufschlussreiche Punkte zu den Kompromissen dieses Ansatzes, insbesondere zu den versteckten Auswirkungen auf die Leistung. Strings sind keine einfachen Tiere, und das Erreichen eines bestimmten Index kann O (n) Zeit dauern, was bedeutet, dass eine Schleife, die einen Index verwendet, O (n ^ 2) sein kann. Du wurdest gewarnt.
Sie müssen nur eine neue
subscript
Funktion hinzufügen , die einen Bereich einnimmt und verwendetadvancedBy()
, um zu dem gewünschten Ort zu gelangen:(Dies sollte definitiv Teil der Sprache sein. Bitte betrügen Sie: // 17158813 )Zum Spaß können Sie
+
den Indizes auch einen Operator hinzufügen :(Ich weiß noch nicht, ob dieser Teil der Sprache sein soll oder nicht.)
quelle
advance<T>(…)
imSwift
Namespace.String.Index
. In diesem Fall geht es nicht so sehr um Optimierung, sondern darum, alles einfach zu halten. Das Hin- und Herwechseln zwischen int und String.Index führt überall zu einem Durcheinander.String.Index
es zu sein), was häufig der Fall ist. Dann können Sie sich nur wünschen, dass all diese Methoden zur Behandlung von Zeichenfolgen mitInt
s funktionieren . Und Sie sind gezwungen, es zu konvertieren,String.Indexes
was zu dem von Ihnen erwähnten Durcheinander führt.Zum Zeitpunkt des Schreibens ist keine Erweiterung perfekt mit Swift 4.2 kompatibel. Hier ist eine, die alle Anforderungen abdeckt, die mir einfallen:
Und dann können Sie verwenden:
string.substring(from: 1, to: 7)
bringt dich:ello,Wo
string.substring(to: 7)
bringt dich:Hello,Wo
string.substring(from: 3)
bringt dich:lo,World!
string.substring(from: 1, length: 4)
bringt dich:ello
string.substring(length: 4, to: 7)
bringt dich:o,Wo
Aktualisiert
substring(from: Int?, length: Int)
, um ab Null zu unterstützen.quelle
"Hello😇😍😘😎📸📀💾∝ℵℶ≹".substring(from: 4, to: 14)
gibt uns:o😇😍😘😎📸📀💾∝ℵℶ
SWIFT 2.0
einfach:
SWIFT 3.0
SWIFT 4.0
Teilstring-Operationen geben anstelle von String eine Instanz vom Typ Teilstring zurück.
quelle
text[text.startIndex..<text.index(text.startIndex, offsetBy: 2)]
Es ist viel einfacher als jede der Antworten hier, sobald Sie die richtige Syntax gefunden haben.
Ich möchte das [und] wegnehmen
Ergebnis ist "ABCDEFGHI", in dem auch startIndex und endIndex verwendet werden können
und so weiter!
PS: Wie in den Anmerkungen angegeben, gibt es in Swift 2 einige Syntaxänderungen, die mit xcode 7 und iOS9 geliefert werden!
Bitte schauen Sie sich diese Seite an
quelle
advance(myString.endIndex, -1)
Syntax hat sich zumyString.endIndex.advancedBy(-1)
Zum Beispiel, um den Vornamen (bis zum ersten Leerzeichen) in meinem vollständigen Namen zu finden:
start
undend
sind hier vom TypString.Index
und werden zum Erstellen einesRange<String.Index>
und im Index-Accessor verwendeten verwendet (wenn in der ursprünglichen Zeichenfolge überhaupt ein Leerzeichen gefunden wird).Es ist schwierig, eine
String.Index
direkt aus einer ganzzahligen Position zu erstellen, wie sie im Eröffnungsbeitrag verwendet wird. Dies liegt daran, dass in meinem Namen jedes Zeichen in Bytes gleich groß wäre. Zeichen mit speziellen Akzenten in anderen Sprachen könnten jedoch mehrere Bytes mehr verwendet haben (abhängig von der verwendeten Codierung). Auf welches Byte sollte sich die Ganzzahl beziehen?Es ist möglich , eine neue erstellen
String.Index
aus einer bestehenden mit den Methodensucc
undpred
die sicherstellen, die korrekte Anzahl von Bytes an den nächsten Codepunkt in der Codierung übersprungen zu erhalten. In diesem Fall ist es jedoch einfacher, nach dem Index des ersten Leerzeichens in der Zeichenfolge zu suchen, um den Endindex zu finden.quelle
Für mich ist das der wirklich interessante Teil Ihrer Frage. String wird zu NSString überbrückt, so die meisten NSString Methoden tun Arbeit direkt auf einem String. Sie können sie frei und ohne nachzudenken verwenden. So funktioniert dies beispielsweise genau so, wie Sie es erwarten:
Aber wie so oft: "Ich habe mein Mojo zum Laufen gebracht, aber es funktioniert einfach nicht bei dir." Sie haben gerade einen der seltenen Fälle ausgewählt, in denen eine parallele Swift-Methode mit identischem Namen existiert , und in einem solchen Fall überschattet die Swift-Methode die Objective-C-Methode. Wenn Sie also sagen
str.substringWithRange
, Swift meint, Sie meinen eher die Swift-Methode als die NSString-Methode - und dann werden Sie abgespritzt, weil die Swift-Methode a erwartetRange<String.Index>
und Sie nicht wissen, wie Sie eine davon erstellen sollen.Der einfache Ausweg besteht darin, Swift daran zu hindern, diese zu überschatten, indem Sie explizit Folgendes tun:
Beachten Sie, dass hier keine wesentlichen zusätzlichen Arbeiten erforderlich sind. "Cast" bedeutet nicht "konvertieren"; Der String ist effektiv ein NSString. Wir sagen nur Swift , wie man sieht bei diesen Variablen für die Zwecke dieser einer Zeile Code.
Der wirklich seltsame Teil dieser ganzen Sache ist, dass die Swift-Methode, die all diese Probleme verursacht, nicht dokumentiert ist. Ich habe keine Ahnung, wo es definiert ist; Es befindet sich nicht im NSString-Header und auch nicht im Swift-Header.
quelle
Range<String.Index>
, oder wir können diese undokumentierte Methode aus dem Weg räumen .In neuem Xcode 7.0 verwenden
quelle
.advancedBy(0)
ist für startIndex nicht erforderlich.Die kurze Antwort ist, dass dies in Swift momentan sehr schwierig ist. Meine Vermutung ist, dass Apple noch eine Menge Arbeit an praktischen Methoden für solche Dinge zu erledigen hat.
String.substringWithRange()
erwartet einenRange<String.Index>
Parameter, und soweit ich das beurteilen kann, gibt es keine Generatormethode für denString.Index
Typ. Sie könnenString.Index
Werte vonaString.startIndex
und zurückbekommen oderaString.endIndex
anrufen.succ()
oder.pred()
auf sie, aber das ist Wahnsinn.Wie wäre es mit einer Erweiterung der String-Klasse, die gute alte
Int
s nimmt?Update: Swift Beta 4 behebt die folgenden Probleme!
So wie es aussieht [in Beta 3 und früher], haben sogar Swift-native Strings einige Probleme mit der Handhabung von Unicode-Zeichen. Das obige Hundesymbol hat funktioniert, aber das Folgende funktioniert nicht:
Ausgabe:
quelle
NSString
ließ mich denken, dass ich nur Swift-nativeString
Methoden verwendete, da ich keinemyString as NSString
Anrufe verwendete.Sie können diese Erweiterungen verwenden, um zu verbessern
substringWithRange
Swift 2.3
Swift 3
Verwendungszweck:
quelle
Beispielcode zum Abrufen von Teilzeichenfolgen in Swift 2.0
(i) Teilzeichenfolge vom Startindex
Eingang:-
Ausgabe:-
(ii) Teilzeichenfolge aus einem bestimmten Index
Eingang:-
Ausgabe:-
Ich hoffe es hilft dir!
quelle
Einfache Lösung mit wenig Code.
Erstellen Sie eine Erweiterung mit grundlegenden Untertiteln, die fast alle anderen Sprachen haben:
Nennen Sie dies einfach mit
quelle
Das funktioniert auf meinem Spielplatz :)
quelle
advance
Aktualisiert für Xcode 7. Fügt String-Erweiterung hinzu:
Verwenden:
Implementierung:
quelle
Versuchen Sie dies auf dem Spielplatz
es wird dir "ello, p" geben
Wenn Sie jedoch den letzten Index größer als die Zeichenfolge auf dem Spielplatz machen, werden alle Zeichenfolgen angezeigt, die Sie nach str: o definiert haben
Range () scheint eine generische Funktion zu sein, sodass es den Typ kennen muss, mit dem es sich handelt.
Sie müssen ihm auch die tatsächliche Zeichenfolge geben, die Sie an Spielplätzen interessiert, da sie alle Stiche nacheinander mit ihrem Variablennamen nacheinander zu halten scheint.
So
gibt "Hallo, Spielplatz str Ich bin der nächste String str2 "
funktioniert auch, wenn str2 mit einem let definiert ist
:) :)
quelle
Rob Napier hatte bereits eine großartige Antwort mit Index gegeben. Aber ich fühlte einen Nachteil darin, da es keine Überprüfung für nicht gebundene Bedingungen gibt. Dies kann zum Absturz neigen. Also habe ich die Erweiterung modifiziert und hier ist sie
Ausgabe unten
Also schlage ich vor, immer nach dem if let zu suchen
quelle
In Swift3
Zum Beispiel: eine Variable "Duke James Thomas", wir müssen "James" bekommen.
quelle
Auf einer Seite von Rob Napier habe ich diese Common String Extensions entwickelt , von denen zwei sind:
Verwendungszweck:
quelle
Range
anstelle vonRange<String.Index>
dank Typinferenz verwenden.So erhalten Sie einen Bereich aus einer Zeichenfolge:
Der entscheidende Punkt ist, dass Sie anstelle von Ganzzahlen einen Wertebereich vom Typ String.Index (dies ist, was der Fortschritt zurückgibt) übergeben.
Der Grund, warum dies notwendig ist, ist, dass Zeichenfolgen in Swift keinen wahlfreien Zugriff haben (aufgrund der variablen Länge der Unicode-Zeichen im Grunde). Das kannst du auch nicht
str[1]
. String.Index arbeitet mit ihrer internen Struktur.Sie können jedoch eine Erweiterung mit einem Index erstellen, die dies für Sie erledigt, sodass Sie nur eine Reihe von Ganzzahlen übergeben können (siehe z. B. Rob Napiers Antwort ).
quelle
Ich habe versucht, mir etwas Pythonisches auszudenken.
Alle Indizes hier sind großartig, aber die Zeiten, in denen ich wirklich etwas Einfaches brauche, sind normalerweise, wenn ich von hinten zählen möchte, z
string.endIndex.advancedBy(-1)
Es werden
nil
Werte sowohl für den Start- als auch für den Endindex unterstützt, wobeinil
der Index bei 0 für Start und Ende bedeuten würdestring.characters.count
.BEARBEITEN
Eine elegantere Lösung:
quelle
Erstellen Sie zuerst den Bereich und dann den Teilstring. Sie können die folgende
fromIndex..<toIndex
Syntax verwenden:quelle
Hier ist ein Beispiel, um nur die Video-ID .ie (6oL687G0Iso) schnell von der gesamten URL abzurufen
quelle
Das vollständige Beispiel finden Sie hier
quelle
http://www.learnswiftonline.com/reference-guides/string-reference-guide-for-swift/ zeigt, dass dies gut funktioniert:
quelle
Nun, ich hatte das gleiche Problem und löste es mit der Funktion "bridgeToObjectiveC ()":
Bitte beachten Sie, dass im Beispiel substringWithRange in Verbindung mit NSMakeRange den Teil der Zeichenfolge übernimmt, der bei Index 6 (Zeichen "W") beginnt und bei Index 6 + 6 Positionen vor (Zeichen "!") Endet.
Prost.
quelle
Sie können jede der Teilstring-Methoden in einer Swift String-Erweiterung verwenden, die ich unter https://bit.ly/JString geschrieben habe .
quelle
Wenn Sie eine haben
NSRange
,NSString
funktioniert die Überbrückung nahtlos. Zum Beispiel habe ich mit gearbeitetUITextFieldDelegate
und wollte schnell den neuen Zeichenfolgenwert berechnen, als er gefragt wurde, ob er den Bereich ersetzen soll.quelle
Einfache Erweiterung für
String
:quelle
Wenn Sie sich nicht für die Leistung interessieren ... ist dies wahrscheinlich die prägnanteste Lösung in Swift 4
Damit können Sie Folgendes tun:
quelle