假设我这里有一个字符串:
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", "--"]
其他回答
作为WMios答案的替代方案,您还可以使用componentsSeparatedByCharactersSet,这在分隔符(空格、逗号等)较多的情况下非常方便。
使用您的特定输入:
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"]
我在寻找loosy拆分,例如PHP的分解,其中空序列包含在结果数组中,这对我很有用:
"First ".split(separator: " ", maxSplits: 1, omittingEmptySubsequences: false)
输出:
["First", ""]
根据Swift 2.2
您只需编写2行代码,就会得到拆分字符串。
let fullName = "FirstName LastName"
var splitedFullName = fullName.componentsSeparatedByString(" ")
print(splitedFullName[0])
print(splitedFullName[1])
享受。:)
Swift 4或更高版本
如果您只需要正确设置人名格式,可以使用PersonNameComponentsFormater。
PersonNameComponentsFormater类提供本地化人名组成部分的表示通过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或更高版本
对于按非字母字符拆分字符串,我们可以使用新的Character属性isLetter:
let fullName = "First Last"
let components = fullName.split{ !$0.isLetter }
print(components) // "["First", "Last"]\n"
我还没有找到能够处理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)
}