我想用大写字母将一个简单的String拆分成一个数组。看起来应该是这样的:
let teststring = "NaCuHHe"
,结果应为:
["Na", "Cu", "H", "He"]
我尝试了以下内容:
func capitalLetters(s: String) -> [Character] {
return s.characters.filter { ("A"..."Z").contains($0) }
}
我搜索了文档和其他网站,但我没有找到任何有用的东西。我在最后。我不知道该怎么做更多因此我真的很新。它仍然只给我资本,我不知道如何改变它给了我第一资本背后的东西。
答案 0 :(得分:7)
(Swift 3)
我们可以让自己受到split
function in Sequence
的实现的启发,并实现我们自己的splitBefore
方法(在分隔符之前拆分,省略空子序列),使分隔符保持在拆分序列中。 / p>
extension Sequence {
func splitBefore(
separator isSeparator: (Iterator.Element) throws -> Bool
) rethrows -> [AnySequence<Iterator.Element>] {
var result: [AnySequence<Iterator.Element>] = []
var subSequence: [Iterator.Element] = []
var iterator = self.makeIterator()
while let element = iterator.next() {
if try isSeparator(element) {
if !subSequence.isEmpty {
result.append(AnySequence(subSequence))
}
subSequence = [element]
}
else {
subSequence.append(element)
}
}
result.append(AnySequence(subSequence))
return result
}
}
使用如下
/* help property */
extension Character {
var isUpperCase: Bool { return String(self) == String(self).uppercased() }
}
/* example usage */
let teststring = "NaCuHHe"
let splitted = teststring
.characters
.splitBefore(separator: { $0.isUpperCase })
.map{String($0)}
print(splitted) // ["Na", "Cu", "H", "He"]
答案 1 :(得分:6)
功能编程风格的另一种解决方案
首先让我们定义一个简单的方法来检查一个Character是否为大写
extension Character {
var isUppercase: Bool { return String(self).uppercased() == String(self) }
}
接下来我们需要大写字符的索引
let indexes = Set(text
.characters
.enumerated()
.filter { $0.element.isUppercase }
.map { $0.offset })
现在我们可以构建结果
let chunks = text
.characters
.map { String($0) }
.enumerated()
.reduce([String]()) { chunks, elm -> [String] in
guard !chunks.isEmpty else { return [elm.element] }
guard !indexes.contains(elm.offset) else { return chunks + [String(elm.element)] }
var chunks = chunks
chunks[chunks.count-1] += String(elm.element)
return chunks
}
["Na", "Cu", "H", "He"]
答案 2 :(得分:3)
另一种方式是:
let input = "NaCuHHe"
var result = [String]()
var lastIndex = 0
for (index, letter) in input.characters.enumerate() where String(letter) != String(letter).lowercaseString {
guard index != lastIndex else { continue }
result += [input.substringWithRange(input.startIndex.advancedBy(lastIndex) ..< input.startIndex.advancedBy(index))]
lastIndex = index
}
result += [input.substringWithRange(input.startIndex.advancedBy(lastIndex) ..< input.endIndex)]
结果为["Na", "Cu", "H", "He"]
答案 3 :(得分:2)
派对有点晚了,但是这里使用空格分隔是一种简单的Swift 3方法。可能不像函数或迭代器方法那样优雅,但它不涉及在现有类上进行任何自定义扩展。
let originalString = "NaCuHHe"
var newStringArray: [String] = []
for character in originalString.characters {
if String(character) == String(character).uppercased() {
newStringArray.append(" ")
}
newStringArray.append(String(character))
}
let newString = newStringArray.joined().trimmingCharacters(in: .whitespacesAndNewlines).components(separatedBy: " ")
print(newString) // Returns ["Na", "Cu", "H", "He"]
答案 4 :(得分:0)
dfri的答案,对Swift 4进行了很大的修改
他的序列扩展名相同,但所用的扩展名不同:
extension Sequence {
func splitBefore(
separator isSeparator: (Iterator.Element) throws -> Bool
) rethrows -> [AnySequence<Iterator.Element>] {
var result: [AnySequence<Iterator.Element>] = []
var subSequence: [Iterator.Element] = []
var iterator = self.makeIterator()
while let element = iterator.next() {
if try isSeparator(element) {
if !subSequence.isEmpty {
result.append(AnySequence(subSequence))
}
subSequence = [element]
}
else {
subSequence.append(element)
}
}
result.append(AnySequence(subSequence))
return result
}
}
使用的字符串扩展名:
extension String {
var isLowercase: Bool {
return self == self.lowercased()
}
var isUppercase: Bool {
return self == self.uppercased()
}
,然后由于Swift 4不推荐使用字符,因此将其用作如下
let teststring = "NaCuHHe"
let splitted = teststring
.splitBefore(separator: { $0.isUppercase })
.map{String($0)}
print(splitted) // ["Na", "Cu", "H", "He"]
答案 5 :(得分:0)
Swift 4中的答案
另一种方法是将最后一个单词(以大写字母开头)弹出到结果列表中,直到在给定的字符串中找不到更多的大写字母为止。
extension String {
func splitWord() -> [String] {
var result = [String]()
var temp = self
var done = false
while !done {
if let index = temp.lastIndex(where: { $0.isUppercase }) {
result.insert(String(temp[index...]), at: 0)
temp = String(temp[..<index])
done = temp.distance(from: temp.startIndex, to: index) == 0
}
else {
result.insert(temp, at: 0)
done = true
}
}
return result
}
}
答案 6 :(得分:0)
使用正则表达式-
func splitYourString(_ s: String) ->[String] {
let regex = try! NSRegularExpression(pattern: "([a-z]*)([A-Z])") //<-Use capturing, `([a-z]*)`->$1, `([A-Z])`->$2
return regex.stringByReplacingMatches(in: s, range: NSRange(0..<s.utf16.count),
withTemplate: "$1 $2").trimmingCharacters(in: .whitespacesAndNewlines) .components(separatedBy: " ")
}
print(splitYourString("NaCuHHe")) //["Na", "Cu", "H", "He"]
答案 7 :(得分:0)
从Apple实施split function in Collection中拆分得到启发。
我所做的是改变子序列索引的创建方式。
在原始实现中,当您按下分隔符时:
在我的实现中:
在分隔符后形成新索引
extension Collection {
@inlinable
public __consuming func split(
maxSplits: Int = Int.max,
omittingEmptySubsequences: Bool = true,
includeSeparator: Bool = false,
whereSeparator isSeparator: (Element) throws -> Bool
) rethrows -> [SubSequence] {
var result: [SubSequence] = []
var subSequenceStart: Index = startIndex
func appendSubsequence(end: Index) -> Bool {
if subSequenceStart == end && omittingEmptySubsequences {
return false
}
result.append(self[subSequenceStart..<end])
return true
}
if maxSplits == 0 || isEmpty {
_ = appendSubsequence(end: endIndex)
return result
}
var subSequenceEnd = subSequenceStart
let cachedEndIndex = endIndex
while subSequenceEnd != cachedEndIndex {
if try isSeparator(self[subSequenceEnd]) {
let didAppend = appendSubsequence(end: subSequenceEnd)
if includeSeparator {
subSequenceStart = subSequenceEnd
formIndex(after: &subSequenceEnd)
} else {
formIndex(after: &subSequenceEnd)
subSequenceStart = subSequenceEnd
}
if didAppend && result.count == maxSplits {
break
}
continue
}
formIndex(after: &subSequenceEnd)
}
if subSequenceStart != cachedEndIndex || !omittingEmptySubsequences {
result.append(self[subSequenceStart..<cachedEndIndex])
}
return result
}
测试结果为:
let splitedString = "NaCuHHe".split(includeSeparator: true, whereSeparator: { $0.isUppercase })
print(splitedString) // ["Na", "Cu", "H", "He"]