Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With Swift replacingOccurrences .regularExpression, how can you PROCESS each match (for example, each match becomes uppercase)?

Say you have

    let fixed = t.replacingOccurrences(
        of: #"(?m)"aa[.\s\S]*?bb"#,
        with: ,
        options: [.regularExpression])

You pass in the text of a file, let's say.

This will of course find all the long strings "aa . . . bb" within the text.

If we do this ...

    let fixed = t.replacingOccurrences(
        of: #"(?m)"aa[.\s\S]*?bb"#,
        with: "WOW! $0",
        options: [.regularExpression])

it will replace each of the "aa . . . bb" with "WOW aa . . . bb".

If we do this ...

    let fixed = t.replacingOccurrences(
        of: #"(?m)"aa[.\s\S]*?bb"#,
        with: "$0 $0 $0",
        options: [.regularExpression])

it will replace each of the "aa . . . bb" with three copies of that "aa . . . bb".

What if we want to replace each of the "aa . . . bb" with an UPPERCASED version of "aa . . . bb"

So conceptually something like this ...

    let fixed = t.replacingOccurrences(
        of: #"(?m)"aa[.\s\S]*?bb"#,
        with: "$0".uppercased(),
        options: [.regularExpression])

Of course, that is not how StringProtocol works, it is meaningless.

Thus, I essentially want to do this:

    let fixed = t.replacingOccurrences(
        of: #"(?m)"aa[.\s\S]*?bb"#,
        with: process( ... the actual value of $0 ... ),
        options: [.regularExpression])

Where func process(_ s: String) -> String.

How do you do that, how do you "get at" the value in that pass of the string protocol (ie, of the $0) and then (say) call a function with it, returning a string to use as the result for that pass?


Just FTR, specifically I want to remove all whitespace/newlines from each of the "aa . . . bb". (Example "1 2 3 aa x y z bb 1 2 3 aa p q r bb" becomes "1 2 3 aaxyzbb 1 2 3 aapqrbb"

like image 325
Fattie Avatar asked Oct 21 '25 03:10

Fattie


1 Answers

Use the Swift regex APIs. There are overloads of replacing(_:with:) that take RegexComponents. You can pass a closure that takes a Match, and computes a replacement.

Example for uppercasing the matches:

let text = "something else aa foo bar baz bb something else"
let regex = /(?m)aa[\s\S]*?bb/
let result = text.replacing(regex, with: { match in
    // you can do whatever you want with "match" here,
    // then return a collection of characters
    match.output.uppercased()
})
print(result)
// something else AA FOO BAR BAZ BB something else
like image 108
Sweeper Avatar answered Oct 22 '25 16:10

Sweeper



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!