If you want to support also from the start or end of the string
extension String {
func slice(from: String, to: String) -> String? {
return (from.isEmpty ? startIndex..<startIndex : range(of: from)).flatMap { fromRange in
(to.isEmpty ? endIndex..<endIndex : range(of: to, range: fromRange.upperBound..<endIndex)).map({ toRange in
String(self[fromRange.upperBound..<toRange.lowerBound])
})
}
}
}
"javascript:getInfo(1,'Info/99/something', 'City Hall',1, 99);"
.slice(from: "'", to: "',") // "Info/99/something"
"javascript:getInfo(1,'Info/99/something', 'City Hall',1, 99);"
.slice(from: "", to: ":") // "javascript"
"javascript:getInfo(1,'Info/99/something', 'City Hall',1, 99);"
.slice(from: ":", to: "") // "getInfo(1,'Info/99/something', 'City Hall',1, 99);"
"javascript:getInfo(1,'Info/99/something', 'City Hall',1, 99);"
.slice(from: "", to: "") // "javascript:getInfo(1,'Info/99/something', 'City Hall',1, 99);"
if you want another syntax, maybe more readable
extension String {
func slice(from: String, to: String) -> String? {
guard let fromRange = from.isEmpty ? startIndex..<startIndex : range(of: from) else { return nil }
guard let toRange = to.isEmpty ? endIndex..<endIndex : range(of: to, range: fromRange.upperBound..<endIndex) else { return nil }
return String(self[fromRange.upperBound..<toRange.lowerBound])
}
}