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

Posted

技术标签:

【中文标题】在 Swift 中将字符串拆分为数组?【英文标题】:Split a String into an array in Swift? 【发布时间】:2014-09-05 03:51:01 【问题描述】:

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

var fullName: String = "First Last"

我想根据空格分割字符串并将值分配给它们各自的变量

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

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

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

【问题讨论】:

嗨,我没有我的 Mac 要检查。但是你可以试试 'fullName.componentsSeparatedByString(string:" ")' 不要复制粘贴,使用自动完成功能,这样就得到了正确的功能。 如果您只分割一个字符,使用fullName.utf8.split( <utf-8 character code> ) 也可以(将.utf8 替换为.utf16 用于UTF-16)。例如,+ 上的拆分可以使用 fullName.utf8.split(43) 另外,有时姓氏中有空格,例如“Daphne du Maurier”或“Charles de Lint” 我觉得这个不错:Split a string by single delimiter, String splitting by multiple delimiters, String splitting by word delimiter 【参考方案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]

【讨论】:

请注意,这实际上是一个底层NSString(导入Foundation时Swift会自动交换它们)。 在 Swift 1.2 中不再是这种情况,Apple 不再自动将 Swift 的 String 转换为 NSString。 此答案适用于 Xcode 7 beta 4 和 Swift 2.0。 Xcode 现在自动完成 Swift String 对象上的 Foundation 方法,而无需将类型转换为 NSString,这在带有 Swift 1.2 的 Xcode 6.4 中不是这种情况。 在我导入 Foundation 之前,它在 REPL 中不起作用。 这完全符合 Xcode 7.2 中的预期(即 fullNameArr 是 [String])。【参考方案2】:

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 类型,拆分的使用变得有点复杂。这意味着 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 

【讨论】:

在我的测试中,componentsSeparatedByString 通常要快得多,尤其是在处理需要拆分为多个部分的字符串时。但是对于 OP 列出的示例,任何一个都足够了。 从 Xcode 6.2b3 开始 split 可以用作split("a:b::c:", $0 == ":", maxSplit: Int.max, allowEmptySlices: false) 请记住,如果您的分隔符长于单个字符,您仍然需要使用旧的componentsSeparatedByString() 方法。虽然说let (firstName, lastName) = split(fullName) $0 == ' ' 很酷,但遗憾的是,这行不通。 @Kashif 那么你可以使用split("a,b;c,d") $0 == "," || $0 == ";"split("a,b;c,d") contains(",;", $0) Xcode 7.0 的正确代码是 let fullNameArr = fullName.characters.split$0 == " ".map(String.init)。尝试编辑,但被拒绝。【参考方案3】:

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

【讨论】:

莫里,这在任何地方都有记录吗?如果我需要拆分单个字符以外的内容怎么办? @NRitH 考虑.componentsSeparatedByCharactersInSet(.whitespaceAndNewlineCharacterSet()) @Crashalot有两个函数:componentsSeparatedByStringcomponentsSeparatedByCharactersInSet @MdRais 你应该问一个新问题,这个问题已经 6 岁了【参考方案4】:

Swift 开发。 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"]

【讨论】:

确保将 import Foundation 添加到您正在使用的课程中。#SavedYouFiveMinutes 注意(Swift 4):如果你有一个像let a="a,,b,c" 这样的字符串并且你使用a.split(separator: ",") 你会得到一个像["a", "b", c"] 这样的数组。这可以使用 omittingEmptySubsequences: false 更改,默认情况下为 true。 Swift 4+ 中的任何多字符拆分?【参考方案5】:

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"

【讨论】:

@DarrellRoot 你只需要映射子字符串fullName.split $0.isWhitespace .map(String.init) 我喜欢这个新 API,但请记住它返回子字符串。我需要字符串(并且想在一般空格上拆分)所以我这样做了:let words = line.split $0.isWhitespace .map String($0) 感谢@LeoDabus 提供您的版本(我的原始评论缺少代码)。另外我建议将 Swift 5 版本移到答案的顶部。【参考方案6】:

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

【讨论】:

我认为最有用的答案,因为您可能希望允许使用 ,; 或任何其他分隔符分隔字符串 @MdRais 您可以使用 for:in 访问字符串中的各个字符 - 请注意,每个元素都是一个 Character【参考方案7】:

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", "hit", "a", "ball", "", "the", "hit", "BALL", "flew", "far", "after", "it", "was", "hit", "", "Hello", "", "Hie", "", "How", "r", "你", ""]

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

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

输出,

["Bob", "hit", "a", "ball", "the", "hit", "BALL", "flew", "far", “after”、“it”、“was”、“hit”、“Hello”、“Hie”、“How”、“r”、“u”]

但请确保 Foundation 已导入。

【讨论】:

请注意,这在某些极端情况下具有不同的行为。例如:"/users/4"split 将产生两个元素,而 components 将产生三个元素,第一个是空字符串。【参考方案8】:

斯威夫特 4

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

【讨论】:

尝试将单词转换为char数据类型。【参考方案9】:

空格问题

通常,人们会一遍又一遍地重新发明这个问题和糟糕的解决方案。这是空间吗? " " 以及 "\n"、"\t" 或一些你从未见过的 unicode 空白字符呢,这在很大程度上是因为它是不可见的。虽然你可以逃脱

弱解

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

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

稳健的解决方案:使用 NSCharacterSet

恕我直言,正确执行此操作的方法是使用NSCharacterSet,因为如前所述,您的空格可能不是您所期望的,Apple 提供了一个空格字符集。要探索提供的各种字符集,请查看 Apple 的 NSCharacterSet developer documentation,然后,如果它不符合您的需求,则只能扩充或构建一个新字符集。

NSCharacterSet 空格

返回一个字符集,其中包含 Unicode General 中的字符 类别 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)

【讨论】:

同意。看到用“”分隔的答案后,我想到的第一件事是:如果输入文本包含几个连续的空格会怎样?如果它有标签怎么办?全角(CJK)空间?等【参考方案10】:

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

By Apple Documentation....

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

【讨论】:

【参考方案11】:

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

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

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

【讨论】:

请注意,这不会返回字符串数组,而是子字符串数组,使用起来很尴尬。【参考方案12】:

斯威夫特 3

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

【讨论】:

【参考方案13】:

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's documentation here。

【讨论】:

【参考方案14】:

只有split 是正确答案,这里有超过2 个空格的区别。

斯威夫特 5

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

【讨论】:

【参考方案15】:

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

【讨论】:

@MdRais let name = "JOHN" print(Array(name))【参考方案16】:

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

【讨论】:

【参考方案17】:

我有一个场景,多个控制字符可以出现在我要拆分的字符串中。我没有维护这些数组,而是让 Apple 处理这部分。

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

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

【讨论】:

【参考方案18】:

我发现了一个有趣的案例,

方法一

var data:[String] = split( featureData )  $0 == "\u003B" 

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

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

这也与 html 代码无关,因为我尝试 stringByRemovingPercentEncoding 但它仍然不起作用

2015 年 10 月 10 日补充

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

var data:[String] = featureData.split $0 == "\u003B"

方法2

var data:[String] = featureData.componentsSeparatedByString("\u003B")

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


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

string.componentsSeparatedByString("")

【讨论】:

我会说这接近于“不是答案”状态,因为它主要是对现有答案的评论。但它指出了一些重要的事情。【参考方案19】:

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

    分配字符串 基于@拆分。

注意: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)

【讨论】:

【参考方案20】:

这会直接

给出一个由拆分部分组成的数组
var fullNameArr = fullName.components(separatedBy:" ")

那么你可以这样使用,

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

【讨论】:

【参考方案21】:

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

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

【讨论】:

【参考方案22】:

斯威夫特 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

【讨论】:

【参考方案23】:

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

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

【讨论】:

【参考方案24】:

这在 Beta 5 中再次发生了变化。哇!它现在是 CollectionType 上的一个方法

旧:

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

新:

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

Apples Release Notes

【讨论】:

【参考方案25】:
let str = "one two"
let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"]

Xcode 7.2 (7C68)

【讨论】:

【参考方案26】:

斯威夫特 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

【讨论】:

【参考方案27】:

字符串处理在 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)

【讨论】:

【参考方案28】:

我正在寻找 loosy 拆分,例如 phpexplode,其中空序列包含在结果数组中,这对我有用:

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

输出:

["First", ""]

【讨论】:

【参考方案29】:

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

【讨论】:

【参考方案30】:

这是我刚刚构建的一种算法,它将String 与数组中的任何Character 分开,如果希望保留带有拆分字符的子字符串,可以将swallow 参数设置为@987654324 @。

Xcode 7.3 - 斯威夫特 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", "--"]

【讨论】:

以上是关于在 Swift 中将字符串拆分为数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何在awk中将分隔字符串拆分为数组?

如何在 C++ 中将数字字符串拆分为数组? [复制]

如何在 C++ 中将字符串拆分为数组

在 C# 中将字符串拆分为字符串数组列表

在c中将长动态字符串拆分为字符串数组

在JS中将对象拆分为对象数组