Reputation: 25974
I am clearly doing something wrong, because this has newer taken me so long to do the following:(Playground code beneath).
Note: Swift 3.1 ~
I am just trying to get 123
out from piz(123)zazz
let aString = "piz(123)zazz"
let startBracket: Character = "("
if let idx1 = aString.characters.index(of: startBracket) {
let pos1 = aString.characters.distance(from: aString.startIndex, to: idx1)
print("Found \(startBracket) at position \(pos1)")
}
else {
print("Not found")
}
let endBracket: Character = ")"
if let idx2 = aString.characters.index(of: endBracket) {
let pos2 = aString.characters.distance(from: aString.startIndex, to: idx2)
print("Found \(startBracket) at position \(pos2)")
}
else {
print("Not found")
}
let range = pos1..<pos2 // << this is not working, I give up!!!
let result_1 = aString.substring(with: range)
Upvotes: 2
Views: 1489
Reputation: 285092
It's much easier:
The start index is the upperBound
of the range of (
in the string
The end index is the lowerBound
of the range of )
in the string
let aString = "piz(123)zazz"
if let openParenthesisRange = aString.range(of: "("),
let closeParenthesisRange = aString.range(of: ")", range: openParenthesisRange.upperBound..<aString.endIndex) {
let range = openParenthesisRange.upperBound..<closeParenthesisRange.lowerBound
let result = aString.substring(with: range)
print(result)
}
else {
print("Not found")
}
Alternatively regular expression, it's more code but it's much more versatile
let string = "piz(123)zazz"
let pattern = #"\((\d+)\)"# // searches for 0 ore more digits between parentheses
do {
let regex = try NSRegularExpression(pattern: pattern)
if let match = regex.firstMatch(in: string, range: NSRange(string.startIndex..., in: string)) {
let range = match.rangeAt(1)
let start = string.index(string.startIndex, offsetBy: range.location)
let end = string.index(start, offsetBy: range.length)
print(string.substring(with: start..<end))
} else {
print("Not Found")
}
} catch {
print("Regex Error:", error)
}
Upvotes: 6
Reputation: 2100
Your pos1
and pos2
are out of scope when you are trying to use. They both have been defined inside of an if
block and their scope ends there itself.
I would suggest declaring them on the top to have them in scope.
let aString = "piz(123)zazz"
let pos1: Int? // You don't need optional here but I prefer it
let pos2: Int?
.
.
.
if let p1 = pos1, p2 = pos2 { // Optional Chaining
let range = pos1..<pos2
}
Upvotes: 3