Reputation: 1674
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
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