Swift: séparer une chaîne en un tableau
Dire que j'ai une chaîne ici:
var fullName: String = "First Last"
je veux diviser la base de chaîne de caractères sur l'espace blanc et assigner les valeurs à leurs variables respectives
var fullNameArr = // something like: fullName.explode(" ")
var firstName: String = fullNameArr[0]
var lastName: String? = fullnameArr[1]
de plus, il arrive que les utilisateurs n'aient pas de nom de famille.
30 réponses
la manière rapide est d'utiliser la fonction globale split
, comme suit:
var fullName = "First Last"
var fullNameArr = split(fullName) {"151900920" == " "}
var firstName: String = fullNameArr[0]
var lastName: String? = fullNameArr.count > 1 ? fullNameArr[1] : nil
avec Swift 2
dans Swift 2, l'utilisation de split devient un peu plus compliquée en raison de l'introduction du type de vue de caractères interne. Cela signifie que String n'adopte plus les protocoles SequenceType ou CollectionType et que vous devez utiliser la propriété .characters
pour accéder à une représentation de type Charactview d'un Instance de chaîne. (Note: Charactview adopte les protocoles SequenceType et CollectionType).
let fullName = "First Last"
let fullNameArr = fullName.characters.split{"151910920" == " "}.map(String.init)
// or simply:
// let fullNameArr = fullName.characters.split{" "}.map(String.init)
fullNameArr[0] // First
fullNameArr[1] // Last
il suffit d'appeler componentsSeparatedByString
méthode sur votre fullName
import Foundation
var fullName: String = "First Last"
let fullNameArr = fullName.componentsSeparatedByString(" ")
var firstName: String = fullNameArr[0]
var lastName: String = fullNameArr[1]
mise à jour pour Swift 3+
import Foundation
let fullName = "First Last"
let fullNameArr = fullName.components(separatedBy: " ")
let name = fullNameArr[0]
let surname = fullNameArr[1]
la méthode la plus simple pour ce faire est d'utiliser des composants séparés par:
Pour Swift 2:
import Foundation
let fullName : String = "First Last";
let fullNameArr : [String] = fullName.componentsSeparatedByString(" ")
// And then to access the individual words:
var firstName : String = fullNameArr[0]
var lastName : String = fullNameArr[1]
Pour Swift 3:
import Foundation
let fullName : String = "First Last"
let fullNameArr : [String] = fullName.components(separatedBy: " ")
// And then to access the individual words:
var firstName : String = fullNameArr[0]
var lastName : String = fullNameArr[1]
Swift Dev. 4,0 (24 mai 2017)
Une nouvelle fonction split
dans Swift 4 ( Bêta ).
import Foundation
let sayHello = "Hello Swift 4 2017";
let result = sayHello.split(separator: " ")
print(result)
sortie:
["Hello", "Swift", "4", "2017"]
valeurs D'accès:
print(result[0]) // Hello
print(result[1]) // Swift
print(result[2]) // 4
print(result[3]) // 2017
Xcode 8.1 / Swift 3.0.1
Voici la façon dont les délimiteurs multiples avec array.
import Foundation
let mathString: String = "12-37*2/5"
let numbers = mathString.components(separatedBy: ["-", "*", "/"])
print(numbers)
sortie:
["12", "37", "2", "5"]
comme alternative à la réponse de WMios, vous pouvez également utiliser componentsSeparatedByCharactersInSet
, ce qui peut être pratique dans le cas où vous avez plus de séparateurs (espace vide, virgule, etc.).
avec votre entrée spécifique:
let separators = NSCharacterSet(charactersInString: " ")
var fullName: String = "First Last";
var words = fullName.componentsSeparatedByCharactersInSet(separators)
// words contains ["First", "Last"]
utilisant des séparateurs multiples:
let separators = NSCharacterSet(charactersInString: " ,")
var fullName: String = "Last, First Middle";
var words = fullName.componentsSeparatedByCharactersInSet(separators)
// words contains ["Last", "First", "Middle"]
Swift 4
let words = "these words will be elements in an array".components(separatedBy: " ")
Xcode 9 Swift 4 ou Xcode 8.2.1 * Swift 3.0.2
si vous avez juste besoin de formater correctement un nom de personne, vous pouvez utiliser PersonNameComponentsFormatter .
la classe Personamecomponentsformatter fournit localisée les représentations des composants du nom d'une personne, comme représenté par un objet Personnamecomposants. Utilisez cette classe pour créer localis noms lors de l'affichage des informations de nom de personne à l'utilisateur.
// iOS (9.0 and later), macOS (10.11 and later), tvOS (9.0 and later), watchOS (2.0 and later)
let nameFormatter = PersonNameComponentsFormatter()
let name = "Mr. Steven Paul Jobs Jr."
// personNameComponents requires iOS (10.0 and later)
if let nameComps = nameFormatter.personNameComponents(from: name) {
nameComps.namePrefix // Mr.
nameComps.givenName // Steven
nameComps.middleName // Paul
nameComps.familyName // Jobs
nameComps.nameSuffix // Jr.
// It can also be convufgured to format your names
// Default (same as medium), short, long or abbreviated
nameFormatter.style = .default
nameFormatter.string(from: nameComps) // "Steven Jobs"
nameFormatter.style = .short
nameFormatter.string(from: nameComps) // "Steven"
nameFormatter.style = .long
nameFormatter.string(from: nameComps) // "Mr. Steven Paul Jobs jr."
nameFormatter.style = .abbreviated
nameFormatter.string(from: nameComps) // SJ
// It can also be use to return an attributed string using annotatedString method
nameFormatter.style = .long
nameFormatter.annotatedString(from: nameComps) // "Mr. Steven Paul Jobs jr."
}
L'espace problème
en général, les gens réinventent ce problème et les mauvaises solutions encore et encore. Est-ce un espace? "" et "\n", "\t" ou certains espaces unicode caractère que vous ne l'avez jamais vu, en grande partie parce qu'il est invisible. Alors que vous pouvez vous en tirer avec
une solution faible
import Foundation
let pieces = "Mary had little lamb".componentsSeparatedByString(" ")
si jamais vous avez besoin de secouer votre emprise sur la réalité regarder une vidéo WWDC sur les chaînes ou les dates. En bref, il est presque toujours mieux de permettre à Apple de résoudre ce genre de tâche banale.
Solution Robuste: Utiliser NSCharacterSet
la façon de le faire correctement, IMHO, est d'utiliser NSCharacterSet
depuis comme indiqué plus tôt votre espace pourrait ne pas être ce que vous attendez et Apple a fourni un jeu de caractères espace. Pour explorer les différents ensembles de caractères fournis, consultez la documentation D'Apple NSCharacterSet developer et ensuite, seulement alors, augmentez ou construisez un nouveau jeu de caractères s'il ne correspond pas à vos besoins.
NSCharacterSet whitespaces
renvoie un jeu de caractères contenant les caractères D'Unicode General Catégorie Zs et TABULATION des caractères (U+0009).
let longerString: String = "This is a test of the character set splitting system"
let components = longerString.components(separatedBy: .whitespaces)
print(components)
Swift 4 rend beaucoup plus facile de diviser des caractères, il suffit d'utiliser la nouvelle fonction split pour les chaînes.
exemple:
let s = "hi, hello"
let a = s.split(separator: ",")
print(a)
Maintenant, vous avez un tableau avec " hi " et "bonjour".
Swift 3
let line = "AAA BBB\t CCC"
let fields = line.components(separatedBy: .whitespaces).filter {!"151900920".isEmpty}
- retourne trois cordes
AAA
,BBB
etCCC
- filtre les champs vides
- Poignées de multiples espaces et de la totalisation des caractères
- si vous voulez manipuler de nouvelles lignes, remplacer
.whitespaces
par.whitespacesAndNewlines
Xcode 8.0 / Swift 3
let fullName = "First Last"
var fullNameArr = fullName.components(separatedBy: " ")
var firstname = fullNameArr[0] // First
var lastname = fullNameArr[1] // Last
:
var fullName: String = "First Last"
fullName += " " // this will help to see the last word
var newElement = "" //Empty String
var fullNameArr = [String]() //Empty Array
for Character in fullName.characters {
if Character == " " {
fullNameArr.append(newElement)
newElement = ""
} else {
newElement += "\(Character)"
}
}
var firsName = fullNameArr[0] // First
var lastName = fullNameArr[1] // Last
j'ai trouvé un cas intéressant ,que
méthode 1
var data:[String] = split( featureData ) { "151900920" == "\u{003B}" }
quand j'ai utilisé cette commande pour séparer un symbole des données qui ont chargé à partir du serveur , il peut se séparer pendant le test en simulateur et synchroniser avec le dispositif de test, mais il ne se divise pas dans publier app, et Ad Hoc
il me faut beaucoup de temps pour traquer cette erreur, elle pourrait être maudite d'une certaine version Swift, ou certains iOS Version ou ni l'un ni l'autre
il ne s'agit pas non plus du code HTML, puisque j'essaie de stringenremovingpercentencoding et il ne fonctionne toujours pas
ajout 10/10/2015
dans Swift 2.0 cette méthode a été remplacée par
var data:[String] = featureData.split {"151910920" == "\u{003B}"}
méthode 2
var data:[String] = featureData.componentsSeparatedByString("\u{003B}")
quand j'ai utilisé cette commande, il peut diviser les mêmes données qui chargent du serveur correctement
Conclusion, je suggère vraiment d'utiliser la méthode 2
string.componentsSeparatedByString("")
j'ai eu un scénario où plusieurs caractères de contrôle peuvent être présents dans la chaîne que je veux partager. Plutôt que de maintenir un tableau de ceux-ci, je laisse Apple gérer cette partie.
fonctionne avec Swift 3.0.1 sur iOS 10:
let myArray = myString.components(separatedBy: .controlCharacters)
la Plupart de ces réponses supposent que l'entrée contient un espace - pas blanc de l'espace, et un seul espace. Si vous pouvez faire cette hypothèse en toute sécurité, alors la réponse acceptée (de bennett) est très élégante et aussi la méthode que je vais aller avec quand je peux.
quand nous ne pouvons pas faire cette hypothèse, une solution plus robuste doit couvrir les siutations suivantes que la plupart des réponses ici ne considèrent pas:
- tabs/newlines / espaces (espaces), y compris récurrents caractères
- espace principal/arrière
- Apple / Linux (
\n
) et Windows (\r\n
) newline characters
pour couvrir ces cas, cette solution utilise regex pour convertir tous les espaces (y compris les caractères newline récurrents et Windows) en un seul espace, trims, puis se divise par un seul space:
Swift 3:
let searchInput = " First \r\n \n \t\t\tMiddle Last "
let searchTerms = searchInput
.replacingOccurrences(
of: "\s+",
with: " ",
options: .regularExpression
)
.trimmingCharacters(in: .whitespaces)
.components(separatedBy: " ")
// searchTerms == ["First", "Middle", "Last"]
ou sans fermetures, Vous pouvez le faire dans Swift 2:
let fullName = "First Last"
let fullNameArr = fullName.characters.split(" ")
let firstName = String(fullNameArr[0])
Swift 4, Xcode 10 et IOS 12 Update 100% working
let fullName = "First Last"
let fullNameArr = fullName.components(separatedBy: " ")
let firstName = fullNameArr[0] //First
let lastName = fullnameArr[1] //Last
voir la documentation D'Apple ici pour plus d'informations.
j'Espère que cela est utile
Swift 4: fendre une chaîne en un tableau. Étape 1: attribuer une chaîne de caractères. étape 2: @ crève. Remarque: variableName.les composants(separatedBy: "split" de mot-clé)
let fullName: String = "First Last @ triggerd event of the session by session storage @ it can be divided by the event of the trigger."
let fullNameArr = fullName.components(separatedBy: "@")
print("split", fullNameArr)
dans Swift 4.1 et Xcode 9.4.1
//This is your str
let str = "This is my String" //Here replace with your string
Option 1
let items = str.components(separatedBy: " ")//Here replase space with your value and result is Array.
//Direct line of code
//let items = "This is my String".components(separatedBy: " ")
let str1 = items[0]
let str2 = items[1]
let str3 = items[2]
let str4 = items[3]
//OutPut
print(items.count)
print(str1)
print(str2)
print(str3)
print(str4)
print(items.first!)
print(items.last!)
Option 2
let items = str.split(separator: " ")
let str1 = String(items.first!)
let str2 = String(items.last!)
//Output
print(items.count)
print(items)
print(str1)
print(str2)
Option 3
let arr = str.split {"151930920" == " "}
print(arr)
Option 4
let line = "BLANCHE: I don't want realism. I want magic!"
print(line.split(separator: " "))
print(line.split(separator: " ", maxSplits: 1))//This can split your string into 2 parts
print(line.split(separator: " ", maxSplits: 2))//This can split your string into 3 parts
print(line.split(separator: " ", omittingEmptySubsequences: false))//array contains empty strings where spaces were repeated.
print(line.split(separator: " ", omittingEmptySubsequences: true))//array not contains empty strings where spaces were repeated.
print(line.split(separator: " ", maxSplits: 4, omittingEmptySubsequences: false))
print(line.split(separator: " ", maxSplits: 3, omittingEmptySubsequences: true))
let str = "one two"
let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"]
Xcode 7.2 (7C68)
Swift 2.2 Erreur de Manipulation et capitalizedString Ajouté :
func setFullName(fullName: String) {
var fullNameComponents = fullName.componentsSeparatedByString(" ")
self.fname = fullNameComponents.count > 0 ? fullNameComponents[0]: ""
self.sname = fullNameComponents.count > 1 ? fullNameComponents[1]: ""
self.fname = self.fname!.capitalizedString
self.sname = self.sname!.capitalizedString
}
disons que vous avez une variable appelée "Hello World" et si vous voulez la diviser et la stocker en deux variables différentes, vous pouvez utiliser comme ceci:
var fullText = "Hello World"
let firstWord = fullText.text?.components(separatedBy: " ").first
let lastWord = fullText.text?.components(separatedBy: " ").last
cela a encore changé en Beta 5. Deee! C'est maintenant une méthode sur CollectionType
:
var fullName = "First Last"
var fullNameArr = split(fullName) {"151900920" == " "}
Nouveau:
var fullName = "First Last"
var fullNameArr = fullName.split {"151910920" == " "}
pour swift 2, XCode 7.1:
let complete_string:String = "Hello world"
let string_arr = complete_string.characters.split {"151900920" == " "}.map(String.init)
let hello:String = string_arr[0]
let world:String = string_arr[1]
selon Swift 2.2
il vous suffit d'écrire 2 lignes de code et vous obtiendrez la chaîne de fente.
let fullName = "FirstName LastName"
var splitedFullName = fullName.componentsSeparatedByString(" ")
print(splitedFullName[0])
print(splitedFullName[1])
de Profiter de. :)
voici un algorithme que je viens de construire, qui va diviser un String
par n'importe quel Character
à partir du tableau et s'il y a un désir de garder les substrats avec des caractères dédoublés, on pourrait définir le paramètre swallow
à true
.
Xcode 7.3-Swift 2.2:
extension String {
func splitBy(characters: [Character], swallow: Bool = false) -> [String] {
var substring = ""
var array = [String]()
var index = 0
for character in self.characters {
if let lastCharacter = substring.characters.last {
// swallow same characters
if lastCharacter == character {
substring.append(character)
} else {
var shouldSplit = false
// check if we need to split already
for splitCharacter in characters {
// slit if the last character is from split characters or the current one
if character == splitCharacter || lastCharacter == splitCharacter {
shouldSplit = true
break
}
}
if shouldSplit {
array.append(substring)
substring = String(character)
} else /* swallow characters that do not equal any of the split characters */ {
substring.append(character)
}
}
} else /* should be the first iteration */ {
substring.append(character)
}
index += 1
// add last substring to the array
if index == self.characters.count {
array.append(substring)
}
}
return array.filter {
if swallow {
return true
} else {
for splitCharacter in characters {
if "151900920".characters.contains(splitCharacter) {
return false
}
}
return true
}
}
}
}
exemple:
"test text".splitBy([" "]) // ["test", "text"]
"test++text--".splitBy(["+", "-"], swallow: true) // ["test", "++" "text", "--"]
la manipulation des chaînes de caractères est encore un défi dans Swift et elle continue de changer de manière significative, comme vous pouvez le voir à partir d'autres réponses. Espérons que les choses se calment et que ça devienne plus simple. C'est la façon de le faire avec l'actuelle version 3.0 de Swift avec plusieurs caractères de séparation.
Swift 3:
let chars = CharacterSet(charactersIn: ".,; -")
let split = phrase.components(separatedBy: chars)
// Or if the enums do what you want, these are preferred.
let chars2 = CharacterSet.alphaNumerics // .whitespaces, .punctuation, .capitalizedLetters etc
let split2 = phrase.components(separatedBy: chars2)
Swift 4
let string = "loremipsum.dolorsant.amet:"
let result = string.components(separatedBy: ".")
print(result[0])
print(result[1])
print(result[2])
print("total: \(result.count)")
Sortie
loremipsum
dolorsant
amet:
total: 3
je cherchais loosy split, comme explode
de PHP où les séquences vides sont inclus dans le tableau résultant, cela a fonctionné pour moi:
"First ".split(separator: " ", maxSplits: 1, omittingEmptySubsequences: false)
sortie:
["First", ""]
Je n'ai pas trouvé la solution qui traiterait les noms avec 3 composants ou plus et supporterait les anciennes versions d'iOS.
struct NameComponentsSplitter {
static func split(fullName: String) -> (String?, String?) {
guard !fullName.isEmpty else {
return (nil, nil)
}
let components = fullName.components(separatedBy: .whitespacesAndNewlines)
let lastName = components.last
let firstName = components.dropLast().joined(separator: " ")
return (firstName.isEmpty ? nil : firstName, lastName)
}
}
cas d'essai réussis:
func testThatItHandlesTwoComponents() {
let (firstName, lastName) = NameComponentsSplitter.split(fullName: "John Smith")
XCTAssertEqual(firstName, "John")
XCTAssertEqual(lastName, "Smith")
}
func testThatItHandlesMoreThanTwoComponents() {
var (firstName, lastName) = NameComponentsSplitter.split(fullName: "John Clark Smith")
XCTAssertEqual(firstName, "John Clark")
XCTAssertEqual(lastName, "Smith")
(firstName, lastName) = NameComponentsSplitter.split(fullName: "John Clark Jr. Smith")
XCTAssertEqual(firstName, "John Clark Jr.")
XCTAssertEqual(lastName, "Smith")
}
func testThatItHandlesEmptyInput() {
let (firstName, lastName) = NameComponentsSplitter.split(fullName: "")
XCTAssertEqual(firstName, nil)
XCTAssertEqual(lastName, nil)
}
var fullName = "James Keagan Michael"
let first = fullName.components(separatedBy: " ").first?.isEmpty == false ? fullName.components(separatedBy: " ").first! : "John"
let last = fullName.components(separatedBy: " ").last?.isEmpty == false && fullName.components(separatedBy: " ").last != fullName.components(separatedBy: " ").first ? fullName.components(separatedBy: " ").last! : "Doe"
- refuser le même prénom et le même nom
- si un nom complet est invalide, prendre la valeur de remplacement "John Doe "