func testFunc(attribString: AttributedString)->AttributedString {
// attribString is a markdown AttributedString for example = "Lorem ipsum dolor <test>first tag</test>sit Donec <test>second tag</test>"
if let range = attribString.range(of: "<test>(.*?)</test>", options: .regularExpression) {
attribString[range].foregroundColor = .red
}
}
the documentation says: range(of) - Finds and returns the range of the first occurrence of a given string within the string.
But how can I find the range of all occurrences in the string with regex so that I can assign it a color or other attribute?
Could a loop be a good idea?
for range in ranges {
attribString[range].foregroundColor = .red
}
Thanks for help
CodePudding user response:
here is a possible solution to achieve ...to keep the <test> </test> tags and color the whole block red...
(adjust the code according to your needs).
It does not involve regex, it is based on the code (sliceMultipleTimes
) at:
Swift Get string between 2 strings in a string
struct ContentView: View {
@State var attStr: AttributedString?
var body: some View {
Text(attStr ?? "nothing")
.onAppear {
let str = "Lorem ipsum dolor <test>first tag</test> sit Donec <test>second tag</test>"
attStr = transform(str, from: "<test>", to: "</test>", with: .red)
}
}
func transform(_ input: String, from: String, to: String, with color: Color) -> AttributedString {
var attInput = AttributedString(input)
let _ = input.components(separatedBy: from).compactMap { sub in
(sub.range(of: to)?.lowerBound).flatMap { endRange in
let s = String(sub[sub.startIndex ..< endRange])
// use `s` for just the middle string
if let theRange = attInput.range(of: (from s to)) {
attInput[theRange].foregroundColor = color
}
}
}
return attInput
}
}