Home > OS >  multiple ranges with regex in AttributeString
multiple ranges with regex in AttributeString

Time:07-29

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
    }
}
  • Related