Swift:将一个string分解成一个数组

说我在这里有一个string:

var fullName: String = "First Last" 

我想分割string基于空格,并将值分配给各自的variables

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

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

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 

Swift 2

在Swift 2中,由于引入了内部的CharacterViewtypes,split的使用变得更加复杂一些。 这意味着String不再采用SequenceType或CollectionType协议,而必须使用.characters属性来访问String实例的CharacterViewtypes表示。 (注意: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 

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

最简单的方法是使用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] 

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

在Swift 4( Beta )中split一个新的函数。

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

作为WMios答案的替代方法,您也可以使用componentsSeparatedByCharactersInSet ,在有更多分隔符(空格,逗号等)的情况下,这可以很方便。

用您的具体input:

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

Xcode 9 Swift 4Xcode 8.2.1•Swift 3.0.2

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

PersonNameComponentsFormatter类提供了PersonNameComponents对象所代表的个人名称组件的本地化表示forms。 在向用户显示人员姓名信息时,使用此类创build本地化名称。


 // 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.givenName // Steven nameComps.middleName // Paul nameComps.familyName // Jobs nameComps.nameSuffix // Jr. nameComps.namePrefix // Mr. // 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." } 

在这里输入图像描述

空白的问题

一般来说,人们总是重蹈覆辙,一遍又一遍地解决这个问题。 这是一个空间吗? “”以及“\ n”,“\ t”或者一些你从未见过的unicode空白字符,这在很大程度上是因为它是不可见的。 虽然你可以逃避

弱解决scheme

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

如果您需要动摇现实,请观看WWDC上的string或datevideo。 总之,允许苹果解决这种平凡的任务几乎总是比较好的。

强大的解决scheme:使用NSCharacterSet

正确地做到这一点,恕我直言,是使用NSCharacterSet因为如前所述你的空白可能不是你所期望的和苹果提供了一个空白字符集。 要探索各种提供的字符集,请查看Apple的NSCharacterSet开发人员文档 ,然后才能增加或构build新的字符集(如果它不符合您的需要)。

NSCharacterSet.whitespaceCharacterSet()

返回包含Unicode常规类别Z和CHARACTER TABULATION(U + 0009)中字符的字符集。

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

稍微更简洁的版本将是

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

斯威夫特4

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

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 

我发现了一个有趣的案例

方法1

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

当我使用这个命令从服务器加载的数据中分离出一些符号时,它可以在模拟器中testing并与testing设备同步时拆分,但不会在发布应用程序中拆分,而且Ad Hoc

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

这不是关于HTML代码,因为我尝试stringByRemovingPercentEncoding ,它仍然不工作

另外10/10/2015

在Swift 2.0中这个方法已经改成了

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

方法2

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

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


结论,我真的build议使用方法2

 string.componentsSeparatedByString("") 

Swift 3

 let line = "AAA BBB\t CCC" let fields = line.components(separatedBy: .whitespaces).filter {!$0.isEmpty} 
  • 返回三个stringAAABBBCCC
  • 筛选出空的领域
  • 处理多个空格和制表符
  • 如果要处理新行,请使用.whitespaces.whitespacesAndNewlinesreplace.whitespacesAndNewlines

或者没有closures,你可以在Swift 2中做到这一点:

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

这些答案中的大多数假设input包含一个空间 – 而不是空白空间,并在这个空间。 如果你能够安全地做出这个假设,那么接受的答案(来自贝内特)是相当优雅的,也是我会尽可能的方法。

当我们不能做出这样的假设时,一个更强大的解决scheme需要覆盖以下大多数答案中没有考虑到的问题:

  • 选项卡/换行符/空格(空白),包括重复出现的字符
  • 前/后空白
  • Apple / Linux( \n Windows( \r\n )换行符

为了覆盖这些情况,此解决scheme使用正则expression式将所有空格(包括循环和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"] 

我有一个场景,我想分割的string中可以有多个控制字符。 我只是让苹果公司处理这一部分,而不是维持这些。

以下在iOS 10上使用Swift 3.0.1:

  let myArray = myString.components(separatedBy: .controlCharacters) 
 let str = "one two" let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"] 

Xcode 7.2(7C68)

Swift 2.2 error handling&大写string增加:

 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 } 

这已经在Beta 5中改变了。Weee! 现在这是一个CollectionType的方法

旧:

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

新:

 var fullName = "First Last" var fullNameArr = fullName.split {$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] 

根据Swift 2.2

你只要写2行代码,你会得到拆分string。

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

请享用。 🙂

这里是我刚刚构build的一个algorithm,它将从数组中的任何Character分割出一个String ,如果有任何希望保留带有分割字符的子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 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", "--"] 

string处理在Swift中仍然是一个挑战,它会不断变化,正如您从其他答案中看到的一样。 希望事情安定下来,变得更简单。 这是使用多个分隔符的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) 

Swift 4使分割字符变得更容易,只需要使用新的分割函数来处理string。

例:

 let s = "hi, hello" s.split(separator: ",") 

现在你有一个“嗨”和“你好”的arrays。

我还没有find解决scheme,将处理名称与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) } } 

通过testing用例:

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