在Swift中将字符串拆分为数组?

823
假设我这里有一个字符串:
var fullName: String = "First Last"

我想根据空格拆分字符串,并将值分配给相应的变量。
var fullNameArr = // something like: fullName.explode(" ") 

var firstName: String = fullNameArr[0]
var lastName: String? = fullnameArr[1]

有时候用户可能没有姓氏。

16
嗨,我没有我的 Mac 可以检查。但您可以尝试使用 'fullName.componentsSeparatedByString(string:" ")'。不要复制粘贴,请使用自动完成功能,这样您就能获得正确的函数。 - David Gölzhäuser
如果您只需要按一个字符拆分,使用 fullName.utf8.split( <utf-8 character code> ) 也可以(对于 UTF-16,请将 .utf8 替换为 .utf16)。例如,使用 fullName.utf8.split(43) 可以拆分 + - Jojodmo
有时候姓氏中间会有空格,比如“达芙妮·杜穆里埃”或者“查尔斯·德林特”。 - Berry
41个回答

1193

只需在您的fullName上调用componentsSeparatedByString方法即可。

import Foundation

var fullName: String = "First Last"
let fullNameArr = fullName.componentsSeparatedByString(" ")

var firstName: String = fullNameArr[0]
var lastName: String = fullNameArr[1]

Swift 3+更新

import Foundation

let fullName    = "First Last"
let fullNameArr = fullName.components(separatedBy: " ")

let name    = fullNameArr[0]
let surname = fullNameArr[1]

4
请注意,实际上这是一个基础的 NSString(在导入 Foundation 时,Swift 会自动交换它们)。 - Can
2
在Swift 1.2中不再是这种情况,苹果不再自动将Swift的String转换为NSString。 - elcuco
8
这个答案适用于Xcode 7 beta 4和Swift 2.0。现在,Xcode可以自动补全Swift字符串对象的基础方法,无需将其类型转换为NSString,这在Swift 1.2的Xcode 6.4中不是这样的。 - Andrew
1
在 REPL 中,直到我导入 Foundation 才能正常工作。 - Velizar Hristov
1
数组下标不会返回可选项。var lastName: String? = fullNameArr[1] 不起作用。 - Bob Spryn
显示剩余6条评论

830

使用全局的split函数是Swift的一种方式,示例如下:

var fullName = "First Last"
var fullNameArr = split(fullName) {$0 == " "}
var firstName: String = fullNameArr[0]
var lastName: String? = fullNameArr.count > 1 ? fullNameArr[1] : nil

使用Swift 2

在Swift 2中,由于引入了内部的CharacterView类型,使用split变得更加复杂。这意味着String不再采用SequenceType或CollectionType协议,而是必须使用.characters属性来访问String实例的CharacterView类型表示。(注意:CharacterView确实采用了SequenceType和CollectionType协议)。

let fullName = "First Last"
let fullNameArr = fullName.characters.split{$0 == " "}.map(String.init)
// or simply:
// let fullNameArr = fullName.characters.split{" "}.map(String.init)

fullNameArr[0] // First
fullNameArr[1] // Last 

104
在我的测试中,componentsSeparatedByString通常更快,特别是在需要将字符串分割成多个部分的情况下。但对于OP列出的示例,两者都可以胜任。 - Casey Perkins
10
从 Xcode 6.2b3 开始,可以使用 _split_ 函数,例如 split("a:b::c:", {$0 == ":"}, maxSplit: Int.max, allowEmptySlices: false) - Pascal
15
请记住,如果您的分隔符不止一个字符长,仍然需要使用旧的componentsSeparatedByString()方法。如果能像这样写出let (firstName, lastName) = split(fullName) {$0 == ' '}就太酷了,但遗憾的是这并行不通。 - NRitH
3
如果您想使用 split("a,b;c,d") {$0 == "," || $0 == ";"}split("a,b;c,d") {contains(",;", $0)},那么可以这样做,它们都可以将字符串 "a,b;c,d" 按照逗号或分号进行分割。 - Ethan
4
Xcode 7.0 的正确代码是 let fullNameArr = fullName.characters.split{$0 == " "}.map(String.init)。我尝试进行编辑,但被拒绝了。 - skagedal
显示剩余13条评论

212

最简单的方法是使用 componentsSeparatedBy:

对于 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]

对于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]

这个有记录在哪里吗,Maury?如果我需要按除单个字符以外的其他内容进行拆分怎么办? - NRitH
13
@NRitH 考虑使用 .componentsSeparatedByCharactersInSet(.whitespaceAndNewlineCharacterSet())。 (意思是建议使用这段代码来分割字符串) - rmp251
@Crashalot,这里有两个函数:componentsSeparatedByStringcomponentsSeparatedByCharactersInSet - rmp251
@MdRais,你应该提出一个新问题,这个问题已经有6年了。 - Wyetro

162

Swift Dev. 4.0(2017年5月24日)

Swift 4中有一个新的函数splitBeta版)。

import Foundation
let sayHello = "Hello Swift 4 2017";
let result = sayHello.split(separator: " ")
print(result)

输出:

["Hello", "Swift", "4", "2017"]

访问数值:

print(result[0]) // Hello
print(result[1]) // Swift
print(result[2]) // 4
print(result[3]) // 2017

Xcode 8.1 / Swift 3.0.1

以下是使用数组处理多个分隔符的方法。

import Foundation
let mathString: String = "12-37*2/5"
let numbers = mathString.components(separatedBy: ["-", "*", "/"])
print(numbers)

输出:

["12", "37", "2", "5"]

9
确保在使用该类时添加import Foundation。#省去您五分钟 - Adrian
4
注意(Swift 4):如果您有一个字符串,如 let a="a,,b,c",并且使用 a.split(separator: ","),则默认情况下会得到一个数组,如 ["a", "b", c"]。这可以通过使用默认情况下为 true 的 omittingEmptySubsequences: false 来更改。 - OderWat
2
Swift 4+ 中有任何多字符分割的方法吗? - pkamb

81

更新 Swift 5.2 的最简单方法

let paragraph = "Bob hit a ball, the hit BALL flew far after it was hit. Hello! Hie, How r u?"

let words = paragraph.components(separatedBy: [",", " ", "!",".","?"])

这将打印:

["Bob", "hit", "a", "ball", "", "the", "hit", "BALL", "flew", "far", "after", "it", "was", "hit", "", "Hello", "", "Hie", "", "How", "r", "u", ""]

然而,如果你想过滤掉空字符串,

let words = paragraph.components(separatedBy: [",", " ", "!",".","?"]).filter({!$0.isEmpty})

输出,

["Bob", "打", "了一个", "球", "这个", "球", "飞了", "很远", "在", "它", "被打后", "Hello", "Hie", "How", "r", "u"]

但请确保已经导入 Foundation


请注意,在某些边缘情况下,它的行为是不同的。例如:使用split"/users/4"进行分割将会得到两个元素,而使用components则会有三个元素,第一个为空字符串。 - Nikolay Suvandzhiev

71

Swift 4 或更高版本

如果您只需要正确格式化人名,可以使用PersonNameComponentsFormatter

PersonNameComponentsFormatter类提供了一个人名的组成部分的本地化表示形式,由PersonNameComponents对象表示。在向用户显示人名信息时,使用此类来创建本地化名称。


// 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 configured 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."
}

输入图像描述

编辑/更新:

Swift 5或更高版本

仅需使用新的字符属性isLetter,即可将字符串按非字母字符拆分。

let fullName = "First Last"

let components = fullName.split{ !$0.isLetter }
print(components)  // "["First", "Last"]\n"

4
你只需要将字符串 fullName 按空格分割后再映射为新的子字符串数组,代码如下:fullName.split { $0.isWhitespace }.map(String.init) - Leo Dabus
2
我喜欢那个新的API,但请记住它返回子字符串。我需要字符串(并且通常想要在空格上拆分),所以我做了这个:let words = line.split{ $0.isWhitespace }.map{ String($0)} 感谢@LeoDabus提供的版本(我的原始评论中缺少代码)。另外,我建议将Swift 5版本移到答案的顶部。 - Darrell Root

58
作为 WMios 回答的替代方案,您还可以使用 componentsSeparatedByCharactersInSet,这在您有更多分隔符(空格、逗号等)的情况下可能会很方便。
针对您特定的输入:
let separators = NSCharacterSet(charactersInString: " ")
var fullName: String = "First Last";
var words = fullName.componentsSeparatedByCharactersInSet(separators)

// words contains ["First", "Last"]

使用多个分隔符:

let separators = NSCharacterSet(charactersInString: " ,")
var fullName: String = "Last, First Middle";
var words = fullName.componentsSeparatedByCharactersInSet(separators)

// words contains ["Last", "First", "Middle"]

3
在我看来,最有用的答案是,因为您可能希望允许使用“,”、“;”或任何其他分隔符来分离字符串。 - Chris
@MdRais,您可以使用for-in来访问字符串中的每个字符 - 请注意,每个元素都是一个Character - Antonio
这应该是被接受的答案。被接受的答案不会通过空格拆分,只会通过空格字符拆分。 - Sam

51

Swift 4

let words = "these words will be elements in an array".components(separatedBy: " ")

尝试将该单词转换为char数据类型。 - Bobby

40

空格问题

通常,人们一遍又一遍地重新发明这个问题和糟糕的解决方案。这是一个空格吗?" " 那么 "\n"、"\t" 或者一些你从未见过的 Unicode 空格字符呢,部分原因是它是不可见的。虽然你可以逃脱

一个弱化的解决方案

import Foundation
let pieces = "Mary had little lamb".componentsSeparatedByString(" ")

如果你需要摆脱现实的束缚,可以观看关于字符串或日期的WWDC视频。总之,让苹果解决这种平凡任务通常是更好的选择。

可靠的解决方案:使用NSCharacterSet

在我看来,正确的做法是使用NSCharacterSet,因为如前所述,你的空格可能不是你期望的那样,而苹果已经提供了一个空格字符集。要探索各种提供的字符集,请查看苹果的NSCharacterSet开发文档,然后只有在不适合你的需求时才增加或构建一个新的字符集。

NSCharacterSet空格

返回一个包含Unicode一般类别Zs和字符制表符(U+0009)的字符集。

let longerString: String = "This is a test of the character set splitting system"
let components = longerString.components(separatedBy: .whitespaces)
print(components)

2
同意。看到按“ ”分割答案后,我首先想到的是:如果输入文本包含多个连续空格会发生什么?如果它有制表符?全角(CJK)空格呢?等等。 - Nicolas Miari

38
Swift 4.2和Xcode 10中,
//This is your str
let str = "This is my String" //Here replace with your string

选项1

let items = str.components(separatedBy: " ")//Here replase space with your value and the result is Array.
//Direct single 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 {$0 == " "}
print(arr)

Option 4
选项4
let line = "BLANCHE:   I don't want realism. I want magic!"
print(line.split(separator: " "))
// Prints "["BLANCHE:", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

苹果官方文档中提到了字符串的分割方法split()

let line = "BLANCHE:   I don't want realism. I want magic!"
print(line.split(separator: " "))
// Prints "["BLANCHE:", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

print(line.split(separator: " ", maxSplits: 1))//This can split your string into 2 parts
// Prints "["BLANCHE:", "  I don\'t want realism. I want magic!"]"

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.
// Prints "["BLANCHE:", "", "", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接