假设我这里有一个字符串:
var fullName: String = "First Last"
我想在空白处拆分字符串,并将值分配给它们各自的变量
var fullNameArr = // something like: fullName.explode(" ")
var firstName: String = fullNameArr[0]
var lastName: String? = fullnameArr[1]
此外,有时用户可能没有姓氏。
假设我这里有一个字符串:
var fullName: String = "First Last"
我想在空白处拆分字符串,并将值分配给它们各自的变量
var fullNameArr = // something like: fullName.explode(" ")
var firstName: String = fullNameArr[0]
var lastName: String? = fullnameArr[1]
此外,有时用户可能没有姓氏。
当前回答
这里是我刚刚构建的一个算法,它将通过数组中的任何字符分割字符串,如果有任何希望保留具有分割字符的子字符串,可以将swall参数设置为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 $0.characters.contains(splitCharacter) {
return false
}
}
return true
}
}
}
}
例子:
"test text".splitBy([" "]) // ["test", "text"]
"test++text--".splitBy(["+", "-"], swallow: true) // ["test", "++" "text", "--"]
其他回答
这在Beta 5中再次发生了变化。哭泣!它现在是CollectionType上的一个方法
旧版本:
var fullName = "First Last"
var fullNameArr = split(fullName) {$0 == " "}
新建:
var fullName = "First Last"
var fullNameArr = fullName.split {$0 == " "}
苹果发行说明
大多数这些答案都假设输入包含一个空格,而不是空白,并且只有一个空格。如果你能安全地做出这样的假设,那么(来自bennett的)公认的答案是相当优雅的,也是我在可能的时候会采用的方法。
当我们无法做出这一假设时,一个更稳健的解决方案需要涵盖以下大多数答案没有考虑的情况:
制表符/换行符/空格(空白),包括重复出现的字符前导/尾随空格Apple/Linux(\n)和Windows(\r\n)换行符
为了涵盖这些情况,此解决方案使用正则表达式将所有空格(包括重复出现的字符和Windows换行符)转换为单个空格,然后修剪,然后拆分为单个空格:
斯威夫特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"]
我还没有找到能够处理3个或更多组件名称并支持较旧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)
}
}
通过测试用例:
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)
}
字符串处理在Swift中仍然是一个挑战,而且它一直在显著变化,从其他答案中可以看到。希望事情稳定下来,事情会变得更简单。这是在当前3.0版本的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)
我在寻找loosy拆分,例如PHP的分解,其中空序列包含在结果数组中,这对我很有用:
"First ".split(separator: " ", maxSplits: 1, omittingEmptySubsequences: false)
输出:
["First", ""]