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


686

说我在这里有一个字符串:

var fullName: String = "First Last"

我想在空白处分割字符串并将值分配给它们各自的变量

var fullNameArr = // something like: fullName.explode(" ") 

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

同样,有时用户可能没有姓氏。


13
嗨,我没有要检查的Mac。但是您可以尝试使用'fullName.componentsSeparatedByString(string:“”)'。不要复制粘贴,请使用自动完成功能,这样您就可以获得正确的功能。
DavidGölzhäuser2014年

如果仅按一个字符进行拆分,则也可以使用fullName.utf8.split( <utf-8 character code> ).utf8.utf16UTF-16 代替)。例如,+可以使用fullName.utf8.split(43)
Jojodmo

另外,有时姓氏中也有空格,例如“ Daphne du Maurier”或“ Charles de Lint”
Berry 17'27

Answers:


784

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中,由于引入了内部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 

98
在我的测试中,componentsSeparatedByString通常要快得多,尤其是在处理需要拆分为多个片段的字符串时。但是对于OP列出的示例,两个都足够。
Casey Perkins 2014年

9
从Xcode 6.2b3开始,split可以用作split("a:b::c:", {$0 == ":"}, maxSplit: Int.max, allowEmptySlices: false)
Pascal

14
请记住,componentsSeparatedByString()如果分隔符比单个字符长,那么您仍然需要使用旧方法。let (firstName, lastName) = split(fullName) {$0 == ' '}可悲的是,这就像它所说的那样酷。
NRitH

3
@Kashif那么你可以使用split("a,b;c,d") {$0 == "," || $0 == ";"}split("a,b;c,d") {contains(",;", $0)}
阮经天

4
Xcode 7.0的正确代码为fullNameArr = fullName.characters.split {$ 0 ==“”} .map(String.init)。试图进行编辑,但遭到拒绝。
skagedal's

1014

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

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]

3
请注意,这实际上是一个基础NSString(Swift在导入时会自动交换它们Foundation)。
可以

1
Swift 1.2不再是这种情况,在Apple中,Apple不再自动将Swift的String转换为NSString。
elcuco

6
此答案适用于Xcode 7 beta 4和Swift 2.0。Xcode现在可以自动完成Swift String对象上的Foundation方法,而无需类型转换为NSString,在带有Swift 1.2的Xcode 6.4中不是这种情况。
安德鲁

1
在我导入Foundation之前,它在REPL中不起作用。
Velizar Hristov

1
[String]与Xcode 7.2中的预期完全一样(即fullNameArr是)。
乔恩·考克斯

184

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

10
@NRitH考虑 .componentsSeparatedByCharactersInSet(.whitespaceAndNewlineCharacterSet())
rmp251

@Crashalot有两个功能:componentsSeparatedByStringcomponentsSeparatedByCharactersInSet
rmp251

130

迅捷开发。4.0(2017年5月24日)

splitSwift 4(Beta)中的新功能。

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

8
确保添加import Foundation到正在使用它的课程中。#SavedYouFiveMinutes
Adrian

4
注意(Swift 4):如果您有一个类似的字符串,let a="a,,b,c"并且使用默认值,您将a.split(separator: ",")得到一个类似的数组["a", "b", c"]。可以使用omittingEmptySubsequences: false默认情况下为true的方式进行更改。
OderWat

2
Swift 4+中有多字符拆分吗?
pkamb

57

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或更高版本

如果只用非字母字符分割字符串,我们可以使用新的Character属性isLetter

let fullName = "First Last"

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

1
@DarrellRoot您只需要映射子字符串fullName.split { $0.isWhitespace }.map(String.init)
Leo Dabus

2
我喜欢这个新API,但请记住,它会返回Substrings。我需要Strings(并希望在一般空格上进行拆分),所以我这样做了:let words = line.split{ $0.isWhitespace }.map{ String($0)} 感谢@LeoDabus提供的版本(我的原始注释中缺少代码)。我也建议将Swift 5版本移到答案的顶部。
Darrell Root

53

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

2
在我看来,最有用的答案,因为你可能希望允许串的分离与,;或任何其他分隔符
克里斯-

49

斯威夫特4

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

34

空格问题

通常,人们会一遍又一遍地重塑此问题和错误的解决方案。这是空间吗?“”以及“ \ n”,“ \ t”或一些您从未见过的Unicode空格字符,这在很大程度上是因为它是不可见的。虽然你可以摆脱

一个弱小的解决方案

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

如果您需要动摇现实,请观看有关字符串或日期的WWDC视频。简而言之,让苹果公司解决这种平凡的任务几乎总是更好。

健壮的解决方案:使用NSCharacterSet

恕我直言,正确使用此方法的方法是使用,NSCharacterSet因为如前所述,您的空格可能不是您所期望的,并且Apple提供了一个空格字符集。要浏览提供的各种字符集,请查看Apple的NSCharacterSet开发人员文档,然后仅在不符合您的需要时扩充或构造一个新的字符集。

NSCharacterSet空格

返回一个字符集,其中包含Unicode常规类别Zs和CHARACTER TABULATION(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 '16

31

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

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

选项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!"]"

由Apple文档...

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

23

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

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

现在,您得到了一个带有“ hi”和“ hello”的数组。


请注意,这不是返回String数组,而是返回使用麻烦的Substring数组。
Lirik

19

Swift 5更新和最简单的方法

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: [",", " ", "!",".","?"])

打印,

[“鲍勃”,“命中”,“一个”,“球”,“”,“该”,“命中”,“球”,“飞”,“远”,“后”,“它”,“是“,” hit“,”“,” Hello“,”“,” Hie“,”“,” How“,” r“,” u“,”“]

但是,如果您要过滤出空字符串,

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

输出,

[“鲍勃”,“命中”,“一个”,“球”,“该”,“命中”,“球”,“飞”,“远”,“后”,“它”,“过去”,“ hit”,“ Hello”,“ Hie”,“ How”,“ r”,“ u”]

但是请确保基金会是进口的


17

迅捷3

let line = "AAA    BBB\t CCC"
let fields = line.components(separatedBy: .whitespaces).filter {!$0.isEmpty}
  • 返回三个字符串AAABBBCCC
  • 筛选出空白字段
  • 处理多个空格和制表符
  • 如果要处理新行,请替换.whitespaces.whitespacesAndNewlines

15

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

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

有关更多信息,请参阅此处Apple文档


13

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

9

我有一个方案,在要拆分的字符串中可以存在多个控制字符。我只是保留了这些部分,而不是维护一系列这些。

以下适用于iOS 10上的Swift 3.0.1:

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

8

我发现一个有趣的案例

方法1

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

当我使用此命令从服务器加载的数据中拆分一些符号时,它可以在模拟器中进行测试时拆分并与测试设备同步,但不会在发布应用程序和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}")

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


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

string.componentsSeparatedByString("")

1
我会说这接近“不是答案”状态,因为它主要是对现有答案的评论。但这指出了一些重要的事情。
rickster

8

大多数这些答案的假设输入包含空格-不的空间,而且是单一的空间。如果您可以安全地做出该假设,那么可接受的答案(来自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"]

6

或者没有闭包,您可以在Swift 2中做到这一点:

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

6

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

  1. 分配字符串
  2. 基于@分裂。

注意:variableName.components(separatedBy:“ split keyword”)

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)

4

斯威夫特4

let string = "loremipsum.dolorsant.amet:"

let result = string.components(separatedBy: ".")

print(result[0])
print(result[1])
print(result[2])
print("total: \(result.count)")

输出量

loremipsum
dolorsant
amet:
total: 3

3

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

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

2
let str = "one two"
let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"]

Xcode 7.2(7C68)


2

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

2

从其他答案中可以看出,字符串处理在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)

2

我一直在寻找松散的拆分,例如PHP explode,在结果数组中包含空序列,这对我来说很有效:

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

输出:

["First", ""]

2

直接给出了一系列拆分零件

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

那么你可以这样使用

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

2

唯一的split答案是正确的,这是两个以上空格的区别。

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

1

Beta 5中再次改变了这一点。现在是CollectionType上的方法

旧:

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

新:

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

苹果发行说明


1

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

1

这是我刚刚构建的一种算法,该算法将数组中的a String进行拆分,Character并且如果希望保留带有拆分字符的子字符串,可以将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", "--"]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.