Hi all. I am not sure what is wrong with my current code. What I am looking to do is change all values of a string with a substring of "around #C"
where # is the temperature. I am converting between farenheit and celsius and i wish to get all substrings then change the correct value depending on the current setting.
So if i have a string where
"This is today. The temperature is around 14C. Tomorrow the temperature will be around 18C"
So the regex would get "around 14C" and "around 18C" and change the values to farenheit. Result would be something like
"This is today. The temperature is around -1F. Tomorrow the temperature will be around -4F"
This is my function.
func formatCorrectDetail(_ detail: String, _ isCelsius: Bool) -> String {
let regex = try! NSRegularExpression(pattern: "around ((\\d+)" + (isCelsius ? "F" : "C") + ")", options: [])
let matches = regex.matches(in: detail, options: [], range: NSRange(location: 0, length: detail.utf16.count))
let formattedString = NSMutableString(string: detail)
for match in matches {
let range = match.range(at: 2)
if let rangeSubstring = Range(range, in: detail),
let temperature = Double(String(detail[rangeSubstring])) {
let val = isCelsius ? NumberTool.far2cel(temperature) : NumberTool.cel2far(temperature)
formattedString.replaceCharacters(in: range, with: val)
}
}
if formattedString.length > 0 {
return String(formattedString)
}
else {
return detail
}
}
The NumberTool.far2cel() and NumberTool.cel2far() are my custom functions to convert between celsius and farehnheit.
Thoughts?
What was not working ?
Problem is that once you replace the first match, the second position's is wrong. Just start from the end.
I wrote far2cel and cel2far, and that works:
let tempMsg = "This is today. The temperature is around 14C. Tomorrow the temperature will be around 18C"
func far2cel(_ val: Double) -> String {
return String((val - 32) / 1.8) + "C"
}
func cel2far(_ val: Double) -> String {
return String((val * 1.8) + 32) + "F"
}
func formatCorrectDetail(_ detail: String, toCelsius: Bool) -> String { // changed for toCelsius, more readable
let regex = try! NSRegularExpression(pattern: "around ((\\d+)" + (toCelsius ? "F" : "C") + ")", options: [])
let matches = regex.matches(in: detail, options: [], range: NSRange(location: 0, length: detail.utf16.count))
let formattedString = NSMutableString(string: detail)
let reversedMatches = matches.reversed()
for match in reversedMatches { // <<-- You need to start at the end
let range = match.range(at: 2)
if let rangeSubstring = Range(range, in: detail),
let temperature = Double(String(detail[rangeSubstring])) {
let rangeForUnit = NSRange(location: range.upperBound, length: 1) // First remove old unit
formattedString.replaceCharacters(in: rangeForUnit, with: "")
let val = toCelsius ? far2cel(temperature) : cel2far(temperature)
formattedString.replaceCharacters(in: range, with: val)
}
}
if formattedString.length > 0 {
return String(formattedString)
}
else {
return detail
}
}
let newTempMsg = formatCorrectDetail(tempMsg, toCelsius: false)
print(newTempMsg)
That gives: This is today. The temperature is around 57.2F. Tomorrow the temperature will be around 64.4F