The regex approach it is already answered so I will post a native Swift approach:
let string = "[anotherWorld] #This is an [hello] amazing [world]"
if let hashTag = string.firstIndex(of: "#"),
let openBracket = string[hashTag...].firstIndex(of: "["),
let closedBracket = string[openBracket...].firstIndex(of: "]") {
let substring = string[string.index(after: openBracket)..<closedBracket]
let result = String(substring)
print(result) // "hello\n"
}
String manipulation in Swift is not very Swifty but you can extend Collection and create some SubSequence
methods to make your life easier:
extension Collection where Element: Equatable {
func firstIndex(after element: Element) -> Index? {
guard let index = firstIndex(of: element) else { return nil }
return self.index(after: index)
}
func subSequence(from element: Element) -> SubSequence? {
guard let index = firstIndex(of: element) else { return nil }
return self[index...]
}
func subSequence(after element: Element) -> SubSequence? {
guard let index = firstIndex(after: element) else { return nil }
return self[index...]
}
func subSequence(upTo element: Element) -> SubSequence? {
guard let index = firstIndex(after: element) else { return nil }
return self[..<index]
}
func subSequence(upThrough element: Element) -> SubSequence? {
guard let index = firstIndex(of: element) else { return nil }
return self[...index]
}
func subSequence(from element: Element, upTo: Element) -> SubSequence? {
guard
let lower = firstIndex(of: element),
let upper = self[lower...].firstIndex(of: upTo)
else { return nil }
return self[lower..<upper]
}
func subSequence(from element: Element, upThrough: Element) -> SubSequence? {
guard
let lower = firstIndex(of: element),
let upper = self[lower...].firstIndex(of: upThrough)
else { return nil }
return self[lower...upper]
}
func subSequence(after element: Element, upTo: Element) -> SubSequence? {
guard
let lower = firstIndex(after: element),
let upper = self[lower...].firstIndex(of: upTo)
else { return nil }
return self[lower..<upper]
}
func subSequence(after element: Element, upThrough: Element) -> SubSequence? {
guard
let lower = firstIndex(after: element),
let upper = self[lower...].firstIndex(of: upThrough)
else { return nil }
return self[lower...upper]
}
}
Now you can get any subsequence between two elements (in the String case a Substring
between two characters):
let string = "[anotherWorld] #This is an [hello] amazing [world]"
let subString = string.subSequence(after: "#")?.subSequence(after: "[", upTo: "]") // "hello"