Mannie
Mannie

Reputation: 1674

Regex engine not matching all occurrences without another pass

Given the following kotlin code;

println(introduceConditionalAndBetweenWordsWith1Passes("'AAA' 'BBB' 'CCC' 'DDDD'"))
println(introduceConditionalAndBetweenWordsWith2Passes("'AAA' 'BBB' 'CCC' 'DDDD'"))


fun introduceConditionalAndBetweenWordsWith1Passes(input: String): String {
    return input.replace("'(.*?)' '(.*?)'".toRegex(), "\'$1\' & '\$2'")

}
fun introduceConditionalAndBetweenWordsWith2Passes(input: String): String {
    val secondPass = input.replace("'(.*?)' '(.*?)'".toRegex(), "\'$1\' & '\$2'")
    return secondPass.replace("'(.*?)' '(.*?)'".toRegex(), "\'$1\' & '\$2'") //2  iterations to resolve the one that don't match the first pass
}

Will produce;

'AAA' & 'BBB' 'CCC' & 'DDDD'
'AAA' & 'BBB' & 'CCC' & 'DDDD'

It seems that the regex engine treats 'AAA' and 'BBB' as 1 match & 'CCC' and 'DDDD' as the second match (and so on) however i want the engine to also match 'BBB' & 'CCC' in this example

Question is; In regex, how would I achieve reading the full string in only a single pass that add an '&' between all words encased in the single quote?

Upvotes: 0

Views: 44

Answers (1)

Tenfour04
Tenfour04

Reputation: 93779

The second word of each pair is part of your match, so it can't be part of the subsequent match. You can look ahead for the second word of each pair, instead of including it in the match:

input.replace("'(.*?)' (?='(.*?)')".toRegex(), "\'$1\' & ")

Upvotes: 1

Related Questions