在 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有两个函数:componentsSeparatedByString
和componentsSeparatedByCharactersInSet
@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
返回三个字符串AAA
、BBB
和CCC
过滤掉空白字段
处理多个空格和制表符
如果要处理新行,请将.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 拆分,例如 php 的 explode
,其中空序列包含在结果数组中,这对我有用:
"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 中将字符串拆分为数组?的主要内容,如果未能解决你的问题,请参考以下文章