拆分字符串而不删除Swift中的分隔符
这可能是重复的。我无法在Swift中找到答案,所以我不确定拆分字符串而不删除Swift中的分隔符,swift,Swift,这可能是重复的。我无法在Swift中找到答案,所以我不确定 按字符分隔的组件set删除分隔符。如果只使用一个可能的字符分隔,则很容易将其添加回。但是当你有一套的时候呢 还有其他拆分方法吗?此方法适用于CollectionTypes,而不是Strings,但应该很容易适应: extension CollectionType { func splitAt(@noescape isSplit: Generator.Element throws -> Bool) rethrows ->
按字符分隔的组件set
删除分隔符。如果只使用一个可能的字符分隔,则很容易将其添加回。但是当你有一套的时候呢
还有其他拆分方法吗?此方法适用于
CollectionTypes
,而不是String
s,但应该很容易适应:
extension CollectionType {
func splitAt(@noescape isSplit: Generator.Element throws -> Bool) rethrows -> [SubSequence] {
var p = startIndex
return try indices
.filter { i in try isSplit(self[i]) }
.map { i in
defer { p = i }
return self[p..<i]
} + [suffixFrom(p)]
}
}
extension CollectionType where Generator.Element : Equatable {
func splitAt(splitter: Generator.Element) -> [SubSequence] {
return splitAt { el in el == splitter }
}
}
或者,此版本使用for循环,并在分隔符后拆分:
extension CollectionType {
func splitAt(@noescape isSplit: Generator.Element throws -> Bool) rethrows -> [SubSequence] {
var p = startIndex
var result: [SubSequence] = []
for i in indices where try isSplit(self[i]) {
result.append(self[p...i])
p = i.successor()
}
if p != endIndex { result.append(suffixFrom(p)) }
return result
}
}
extension CollectionType where Generator.Element : Equatable {
func splitAt(splitter: Generator.Element) -> [SubSequence] {
return splitAt { el in el == splitter }
}
}
let sentence = "Hello, my name is oisdk. This should split: but only at punctuation!"
let puncSet = Set("!.,:".characters)
sentence
.characters
.splitAt(puncSet.contains)
.map(String.init)
// ["Hello,", " my name is oisdk.", " This should split:", " but only at punctuation!"]
或者,如果您想将最快捷的功能整合到一个功能中(延迟
、抛出
、协议扩展、邪恶的平面地图
、防护
,以及可选功能):
Swift 3和4版本
感谢Oisdk让我思考。我来这里是想找到这个问题的答案。没有找到我要查找的内容,并通过反复调用.split(…)来构建它。它并不优雅,但您可以选择保留哪些分隔符,哪些不保留。有可能有一种方法可以避免字符串-子字符串转换,有人知道吗
var input = """
{All those moments will be (lost in time)},
like tears [in rain](. ([(Time to)] die))
"""
var separator: Character = "!"
var output: [String] = []
repeat {
let tokens = input.split(
maxSplits: 1,
omittingEmptySubsequences: false,
whereSeparator: {
switch $0 {
case "{", "}", "(", ")", "[", "]": // preserve
separator = $0; return true
case " ", "\n", ",", ".": // omit
separator = " "; return true
default:
return false
}
}
)
if tokens[0] != "" {
output.append(String(tokens[0]))
}
guard tokens.count == 2 else { break }
if separator != " " {
output.append(String(separator))
}
input = String(tokens[1])
} while true
for token in output { print("\(token)") }
在上述情况下,选择器不是实际设置的。我不需要,但如果你需要的话,只要做这些声明
let preservedDelimiters: Set<Character> = [ "{", "}", "(", ")", "[", "]" ]
let omittedDelimiters: Set<Character> = [ " ", "\n", ",", "." ]
是的,但是如果集合看起来像这样会产生有趣的字符串,但不是我真正需要的。=>对“如果只是连接分隔符会怎么样”的响应非常完美,特别是像上一个一样;)<代码>扩展集合{func split(在isSplit:(元素)抛出->Bool)rethrows->[SubSequence]{var p=startIndex return try index.compactMap{i in-guard try isSplit(self[i])否则{return nil}延迟{p=index(在:i之后)}返回self p.i]}+(p!=endIndex?[后缀(from:p)]:[])}swift4.1要求使用
compactMap
而不是flatMap
extension Collection {
func splitAt(isSplit: (Iterator.Element) throws -> Bool) rethrows -> [SubSequence] {
var p = self.startIndex
var result:[SubSequence] = try self.indices.flatMap {
i in
guard try isSplit(self[i]) else {
return nil
}
defer {
p = self.index(after: i)
}
return self[p...i]
}
if p != self.endIndex {
result.append(suffix(from: p))
}
return result
}
}
var input = """
{All those moments will be (lost in time)},
like tears [in rain](. ([(Time to)] die))
"""
var separator: Character = "!"
var output: [String] = []
repeat {
let tokens = input.split(
maxSplits: 1,
omittingEmptySubsequences: false,
whereSeparator: {
switch $0 {
case "{", "}", "(", ")", "[", "]": // preserve
separator = $0; return true
case " ", "\n", ",", ".": // omit
separator = " "; return true
default:
return false
}
}
)
if tokens[0] != "" {
output.append(String(tokens[0]))
}
guard tokens.count == 2 else { break }
if separator != " " {
output.append(String(separator))
}
input = String(tokens[1])
} while true
for token in output { print("\(token)") }
let preservedDelimiters: Set<Character> = [ "{", "}", "(", ")", "[", "]" ]
let omittedDelimiters: Set<Character> = [ " ", "\n", ",", "." ]
whereSeparator: {
if preservedDelimiters.contains($0) {
separator = $0
return true
} else if omittedDelimiters.contains($0) {
separator = " "
return true
} else {
return false
}
}