切片字符串 Swift
Slicing Strings Swift
我想将一个很长的字符串从一个词分割成另一个词。我想得到这些词之间的子串。
为此,我使用以下字符串扩展名:
extension String {
func slice(from: String, to: String) -> String? {
guard let rangeFrom = range(of: from)?.upperBound else { return nil }
guard let rangeTo = self[rangeFrom...].range(of: to)?.lowerBound else { return nil }
return String(self[rangeFrom..<rangeTo])
}
效果非常好,但我的原始字符串包含一些 "from" "to"-words 我需要这两个词之间的每个子字符串,但是我的扩展我只能得到第一个子串。
示例:
let raw = "id:244476end36475677id:383848448end334566777788id:55678900end543"
我想从此原始字符串示例中获取以下子字符串:
sub1 = "244476"
sub2 = "383848448"
sub3 = "55678900"
如果我打电话:
var text = raw.slice(from: "id:" , to: "end")
我只得到第一次出现 (text = "244476")
感谢您的阅读。每个答案都会很好。
PS:我在 Whosebug 中制作代码片段时总是出错。
与其尝试从头到尾解析字符串,不如结合使用现有方法将其转换为所需结果。以下是我将如何做到这一点:
import Foundation
let raw = "id:244476end36475677id:383848448end334566777788id:55678900end543"
let result = raw
.components(separatedBy: "id:")
.filter{ ![=10=].isEmpty }
.map { segment -> String in
let slices = segment.components(separatedBy: "end")
return slices.first! // Removes the `end` and everything thereafter
}
print(result) // => ["244476", "383848448", "55678900"]
您可以使用 while 循环重复从该点到字符串末尾的搜索并使用 map 从结果范围中获取子字符串:
extension StringProtocol {
func ranges<S:StringProtocol,T:StringProtocol>(between start: S, and end: T, options: String.CompareOptions = []) -> [Range<Index>] {
var ranges: [Range<Index>] = []
var startIndex = self.startIndex
while startIndex < endIndex,
let lower = self[startIndex...].range(of: start, options: options)?.upperBound,
let range = self[lower...].range(of: end, options: options) {
let upper = range.lowerBound
ranges.append(lower..<upper)
startIndex = range.upperBound
}
return ranges
}
func substrings<S:StringProtocol,T:StringProtocol>(between start: S, and end: T, options: String.CompareOptions = []) -> [SubSequence] {
ranges(between: start, and: end, options: options).map{self[[=10=]]}
}
}
游乐场测试:
let string = """
your text
id:244476end
id:383848448end
id:55678900end
the end
"""
let substrings = string.substrings(between: "id:", and: "end") // ["244476", "383848448", "55678900"]
我想将一个很长的字符串从一个词分割成另一个词。我想得到这些词之间的子串。 为此,我使用以下字符串扩展名:
extension String {
func slice(from: String, to: String) -> String? {
guard let rangeFrom = range(of: from)?.upperBound else { return nil }
guard let rangeTo = self[rangeFrom...].range(of: to)?.lowerBound else { return nil }
return String(self[rangeFrom..<rangeTo])
}
效果非常好,但我的原始字符串包含一些 "from" "to"-words 我需要这两个词之间的每个子字符串,但是我的扩展我只能得到第一个子串。
示例:
let raw = "id:244476end36475677id:383848448end334566777788id:55678900end543"
我想从此原始字符串示例中获取以下子字符串:
sub1 = "244476"
sub2 = "383848448"
sub3 = "55678900"
如果我打电话:
var text = raw.slice(from: "id:" , to: "end")
我只得到第一次出现 (text = "244476")
感谢您的阅读。每个答案都会很好。
PS:我在 Whosebug 中制作代码片段时总是出错。
与其尝试从头到尾解析字符串,不如结合使用现有方法将其转换为所需结果。以下是我将如何做到这一点:
import Foundation
let raw = "id:244476end36475677id:383848448end334566777788id:55678900end543"
let result = raw
.components(separatedBy: "id:")
.filter{ ![=10=].isEmpty }
.map { segment -> String in
let slices = segment.components(separatedBy: "end")
return slices.first! // Removes the `end` and everything thereafter
}
print(result) // => ["244476", "383848448", "55678900"]
您可以使用 while 循环重复从该点到字符串末尾的搜索并使用 map 从结果范围中获取子字符串:
extension StringProtocol {
func ranges<S:StringProtocol,T:StringProtocol>(between start: S, and end: T, options: String.CompareOptions = []) -> [Range<Index>] {
var ranges: [Range<Index>] = []
var startIndex = self.startIndex
while startIndex < endIndex,
let lower = self[startIndex...].range(of: start, options: options)?.upperBound,
let range = self[lower...].range(of: end, options: options) {
let upper = range.lowerBound
ranges.append(lower..<upper)
startIndex = range.upperBound
}
return ranges
}
func substrings<S:StringProtocol,T:StringProtocol>(between start: S, and end: T, options: String.CompareOptions = []) -> [SubSequence] {
ranges(between: start, and: end, options: options).map{self[[=10=]]}
}
}
游乐场测试:
let string = """
your text
id:244476end
id:383848448end
id:55678900end
the end
"""
let substrings = string.substrings(between: "id:", and: "end") // ["244476", "383848448", "55678900"]