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

假设我在这里有一个字符串:

var fullName: String = "First Last"

我想在空格上拆分字符串并将值分配给它们各自的变量

var fullNameArr = // something like: fullName.explode(" ")
var firstName: String = fullNameArr[0]var lastName: String? = fullnameArr[1]

此外,有时用户可能没有姓氏。

725797 次浏览

最简单的方法是使用组件分离:

对于Swift 2:

import Foundationlet 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]

只需在您的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]

作为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"]

Swift的方法是使用全局split函数,如下所示:

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

Swift2

在Swift 2中,拆分的使用变得有点复杂,这是因为引入了内部的特征视图类型。这意味着String不再采用SequenceType或ColltionType协议,你必须使用.characters属性来访问String实例的特征视图表示。(注意:特征视图确实采用了SequenceType和ColltionType协议)。

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] // FirstfullNameArr[1] // Last

Swift 4或更高版本

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

角色名称组件格式类提供本地化的表示一个人的名字的组成部分,所代表的通过个人名称组件对象。使用此类创建本地化向用户显示人名信息时的名称。


// 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    // StevennameComps.middleName   // PaulnameComps.familyName   // JobsnameComps.nameSuffix   // Jr.
// It can also be configured to format your names// Default (same as medium), short, long or abbreviated
nameFormatter.style = .defaultnameFormatter.string(from: nameComps)   // "Steven Jobs"
nameFormatter.style = .shortnameFormatter.string(from: nameComps)   // "Steven"
nameFormatter.style = .longnameFormatter.string(from: nameComps)   // "Mr. Steven Paul Jobs jr."
nameFormatter.style = .abbreviatednameFormatter.string(from: nameComps)   // SJ
// It can also be use to return an attributed string using annotatedString methodnameFormatter.style = .longnameFormatter.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"

我发现了一个有趣的案例

方法1

var data:[String] = split( featureData ) { $0 == "\u{003B}" }

当我使用此命令拆分一些符号从服务器加载的数据时,它可以在模拟器中测试时拆分并与测试设备同步,但它不会在发布应用程序和广告中拆分

我花了很多时间来跟踪这个错误,它可能被一些Swift版本诅咒,或者一些iOS版本,或者两者都没有

它也不是关于超文本标记语言代码,因为我尝试字符串通过删除百分比编码,但它仍然不起作用

添加10/10/2015

在Swift 2.0中,此方法已更改为

var data:[String] = featureData.split {$0 == "\u{003B}"}

方法2

var data:[String] = featureData.componentsSeparatedByString("\u{003B}")

当我使用这个命令时,它可以正确地分割从服务器加载的相同数据


中结论我真的建议用这个方法

string.componentsSeparatedByString("")

这在Beta 5中再次发生了变化。Weee!它现在是集合类型上的方法

旧:

var fullName = "First Last"var fullNameArr = split(fullName) {$0 == " "}

新增:

var fullName = "First Last"var fullNameArr = fullName.split {$0 == " "}

苹果发行说明

或者没有闭包,你可以在Swift 2中这样做:

let fullName = "First Last"let fullNameArr = fullName.characters.split(" ")let firstName = String(fullNameArr[0])

对于Swift 2,XCode 7.1:

let complete_string:String = "Hello world"let string_arr =  complete_string.characters.split {$0 == " "}.map(String.init)let hello:String = string_arr[0]let world:String = string_arr[1]

空白问题

一般来说,人们一遍又一遍地重新发明这个问题和糟糕的解决方案。这是一个空格吗?“”还有“\n”、“\t”或一些你从未见过的Unicode空格字符,很大程度上是因为它是看不见的。虽然你可以逃脱惩罚

弱解

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

如果你需要摆脱对现实的控制,请观看关于字符串或日期的WWDC视频。简而言之,让Apple解决这种平凡的任务几乎总是更好的。

健壮的解决方案:使用NSChartSet

正确的方法是使用NSCharacterSet,因为如前所述,您的空格可能不是您期望的,并且Apple提供了空格字符集。要探索提供的各种字符集,请查看Apple的开发人员留档,然后,只有在那时,如果它不适合您的需求,才会增强或构建一个新的字符集。

空格

返回包含Unicode General中字符的字符集类别Z和字符表(U+0009)。

let longerString: String = "This is a test of the character set splitting system"let components = longerString.components(separatedBy: .whitespaces)print(components)
let str = "one two"let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"]

Xcode 7.2(7C68)

根据Swift 2.2

您只需编写2行代码,您将获得拆分字符串。

let fullName = "FirstName LastName"var splitedFullName = fullName.componentsSeparatedByString(" ")print(splitedFullName[0])print(splitedFullName[1])

享受:)

这是我刚刚构建的一个算法,它将从数组中的任何Character拆分String,如果有任何希望保留带有拆分字符的子字符串,可以将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 charactersif lastCharacter == character {
substring.append(character)
} else {
var shouldSplit = false
// check if we need to split alreadyfor splitCharacter in characters {// slit if the last character is from split characters or the current oneif character == splitCharacter || lastCharacter == splitCharacter {
shouldSplit = truebreak}}
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 arrayif 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", "--"]

Swift 2.2错误处理和大写字符串添加:

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!.capitalizedStringself.sname = self.sname!.capitalizedString}

这些答案中的大多数假设输入包含一个空格-而不是白色空格,并且只有一个空格。如果你能安全地做出这个假设,那么接受的答案(来自Bennett)非常优雅,也是我将在可能的时候使用的方法。

当我们不能做出这个假设时,一个更强大的解决方案需要涵盖以下情况,这里的大多数答案都没有考虑到:

  • 制表符/换行符/空格(空格),包括经常性个字符
  • 前导/尾随空格
  • Apple/Linux(\n Windows(\r\n)换行符

为了涵盖这些情况,此解决方案使用regex将所有空格(包括循环和Windows换行符)转换为单个空格,修剪,然后由单个空格拆分:

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"]

Xcode 8.0/Swift 3

let fullName = "First Last"var fullNameArr = fullName.components(separatedBy: " ")
var firstname = fullNameArr[0] // Firstvar lastname = fullNameArr[1] // Last

长途跋涉:

var fullName: String = "First Last"fullName += " " // this will help to see the last word
var newElement = "" //Empty Stringvar fullNameArr = [String]() //Empty Array
for Character in fullName.characters {if Character == " " {fullNameArr.append(newElement)newElement = ""} else {newElement += "\(Character)"}}

var firsName = fullNameArr[0] // Firstvar lastName = fullNameArr[1] // Last

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

Swift 4中的新函数splitβ)。

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

输出:

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

访问值:

print(result[0]) // Helloprint(result[1]) // Swiftprint(result[2]) // 4print(result[3]) // 2017

Xcode 8.1/Swift 3.0.1

这里是多个分隔符与数组的方式。

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

输出:

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

我有一个场景,在我想要拆分的字符串中可以存在多个控制字符。与其维护这些数组,我只是让Apple处理这部分。

以下代码适用于iOS10上的Swift 3.0.1:

let myArray = myString.components(separatedBy: .controlCharacters)

字符串处理在Swift中仍然是一个挑战,并且它不断发生显着变化,正如您从其他答案中看到的那样。希望事情稳定下来并变得更简单。这是当前3.0版本的具有多个分隔符的Swift的方法。

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 etclet split2 = phrase.components(separatedBy: chars2)

Swift 4使拆分字符变得更加容易,只需使用Strings的新拆分功能即可。

示例:let s="hi, hello"设a=s.split(分隔符:",")打印(a)

现在你得到了一个带有'hi'和'hello'的数组。

Swift4

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

我还没有找到可以处理具有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.lastlet 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)}
let fullName : String = "Steve.Jobs"let fullNameArr : [String] = fullName.components(separatedBy: ".")
var firstName : String = fullNameArr[0]var lastName : String = fullNameArr[1]

Swift3

let line = "AAA    BBB\t CCC"let fields = line.components(separatedBy: .whitespaces).filter {!$0.isEmpty}
  • 返回三个字符串AAABBBCCC
  • 过滤掉空字段
  • 处理多个空格和制表字符
  • 如果要处理新行,请将.whitespaces替换为.whitespacesAndNewlines
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"
  • 禁止相同的名字和姓氏
  • 如果全名无效,则取占位符值“John Doe”

在Swift 4中将字符串拆分为数组的步骤。

  1. 赋值字符串
  2. 基于@拆分。

注意:variableName.components(分隔:“分割关键字”)

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)

假设您有一个名为“Hello World”的变量,如果您想将其拆分并存储为两个不同的变量,您可以像这样使用:

var fullText = "Hello World"let firstWord = fullText.text?.components(separatedBy: " ").firstlet lastWord = fullText.text?.components(separatedBy: " ").last

Swift4

let string = "loremipsum.dolorsant.amet:"
let result = string.components(separatedBy: ".")
print(result[0])print(result[1])print(result[2])print("total: \(result.count)")

产出

loremipsumdolorsantamet:total: 3

Swift 4,Xcode 10和iOS12更新100%工作

let fullName = "First Last"let fullNameArr = fullName.components(separatedBy: " ")let firstName = fullNameArr[0] //Firstlet lastName = fullNameArr[1] //Last

有关更多信息,请参阅Apple留档了

我正在寻找松散拆分,例如PHP的explode,其中空序列包含在结果数组中,这对我有用:

"First ".split(separator: " ", maxSplits: 1, omittingEmptySubsequences: false)

输出:

["First", ""]

Swift 4.2和Xcode 10

//This is your strlet 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]//OutPutprint(items.count)print(str1)print(str2)print(str3)print(str4)print(items.first!)print(items.last!)

备选案文2

let items = str.split(separator: " ")let str1 = String(items.first!)let str2 = String(items.last!)//Outputprint(items.count)print(items)print(str1)print(str2)

备选案文3

let arr = str.split {$0 == " "}print(arr)

备选办法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!"]"

由苹果文档……

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

您可以使用此通用函数并添加任何要分隔的字符串

func separateByString(String wholeString: String, byChar char:String) -> [String] {
let resultArray = wholeString.components(separatedBy: char)return resultArray}
var fullName: String = "First Last"let array = separateByString(String: fullName, byChar: " ")var firstName: String = array[0]var lastName: String = array[1]print(firstName)print(lastName)

这是Swift 4.2的String和CSV文件,位于20181206 1610

var dataArray : [[String]] = []let path = Bundle.main.path(forResource: "csvfilename", ofType: "csv")let url = URL(fileURLWithPath: path!)do {let data = try Data(contentsOf: url)let content = String(data: data, encoding: .utf8)let parsedCSV = content?.components(separatedBy: "\r\n").map{ $0.components(separatedBy: ";") }for line in parsedCSV!{dataArray.append(line)}}catch let jsonErr {print("\n   Error read CSV file: \n ", jsonErr)}
print("\n MohNada 20181206 1610 - The final result is \(dataArray)  \n ")

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","打","a","球",","the","打","球","飞","远","之后","它","是","打",","你好",","嗨",","如何","r","u",""]

但是,如果您想过滤掉空字符串,

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

输出,

["Bob","打","a","球","the","打","球","飞","远","后","它","是","命中","你好","嗨","如何","r","u"]

但请确保基金会是导入的。

这给出了分割部分直接阵列

var fullNameArr = fullName.components(separatedBy:" ")

然后你可以这样使用,

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

只有split是正确答案,以下是超过2个空格的差异。

Swift5

var temp = "Hello world     ni hao"let arr  = temp.components(separatedBy: .whitespacesAndNewlines)// ["Hello", "world", "", "", "", "", "ni", "hao"]let arr2 = temp.components(separatedBy: " ")// ["Hello", "world", "", "", "", "", "ni", "hao"]let arr3 = temp.split(whereSeparator: {$0 == " "})// ["Hello", "world", "ni", "hao"]

Don Vaughn的回答开始,我喜欢使用正则表达式。我很惊讶这只是第二个正则表达式答案。然而,如果我们能在一个split方法中解决这个问题,而不是多个方法,那就太好了。

我还受到Mithra Singam的回答的启发,排除了所有标点符号和空格。然而,必须创建一个不允许的字符列表对我来说并不好。

  • \w-字母或数字符号的正则表达式。没有标点符号。
let foo = "(..#   Hello,,(---- World   ".split {String($0).range(of: #"\w"#, options: .regularExpression) == nil}print(foo) // Prints "Hello World"

假设您对所有Unicode都不满意。只使用ASKII字母和数字怎么样?

let bar = "(..#   Hello,,(---- World   ".split {!($0.isASCII && ($0.isLetter || $0.isNumber))}print(bar) // Prints "Hello World"

离线:

对于搜索如何用子串拆分字符串(不是字符)的人,这里是工作解决方案:

// TESTINGlet str1 = "Hello user! What user's details? Here user rounded with space."let a = str1.split(withSubstring: "user") // <-------------- HERE IS A SPLITprint(a) // ["Hello ", "! What ", "\'s details? Here ", " rounded with space."]
// testing the resultvar result = ""for item in a {if !result.isEmpty {result += "user"}result += item}print(str1) // "Hello user! What user's details? Here user rounded with space."print(result) // "Hello user! What user's details? Here user rounded with space."print(result == str1) // true
/// Extension providing `split` and `substring` methods.extension String {    
/// Split given string with substring into array/// - Parameters:///   - string: the string///   - substring: the substring to search/// - Returns: array of componentsfunc split(withSubstring substring: String) -> [String] {var a = [String]()var str = selfwhile let range = str.range(of: substring) {let i = str.distance(from: str.startIndex, to: range.lowerBound)let j = str.distance(from: str.startIndex, to: range.upperBound)let left = str.substring(index: 0, length: i)let right = str.substring(index: j, length: str.length - j)a.append(left)str = right}if !str.isEmpty {a.append(str)}return a}    
/// the length of the stringpublic var length: Int {return self.count}    
/// Get substring, e.g. "ABCDE".substring(index: 2, length: 3) -> "CDE"////// - parameter index:  the start index/// - parameter length: the length of the substring////// - returns: the substringpublic func substring(index: Int, length: Int) -> String {if self.length <= index {return ""}let leftIndex = self.index(self.startIndex, offsetBy: index)if self.length <= index + length {return String(self[leftIndex..<self.endIndex])}let rightIndex = self.index(self.endIndex, offsetBy: -(self.length - index - length))return String(self[leftIndex..<rightIndex])}
}

最简单的解决办法是

let fullName = "First Last"
let components = fullName.components(separatedBy: .whitespacesAndNewlines).compactMap { $0.isEmpty ? nil : $0 }

这将处理一行中不同类型(空格、制表符、换行符等)的多个空格,并且只返回一个两个元素的数组,您可以更改CharacterSet以包含更多您喜欢的字符,如果您想获取cleaver,您可以使用正则表达式解码器,这允许您将可用于解码字符串的正则表达式直接写入您自己的实现解码协议的类/结构中。对于这样的事情来说,这是过度杀戮,但如果您将其用作更复杂字符串的示例,它可能更有意义。

将字符串拆分为数组的简单方法

var fullName: String = "First Last";
var fullNameArr = fullName.componentsSeparatedByString(" ")
var firstName: String = fullNameArr[0]var lastName: String = fullNameArr[1]