Split string by repeatable delimiter in Java/Kotlin

Viewed 140

I am splitting a string by a repeatable delimiter, and am also intended to keep the delimiters as well.

val str = "xxoooooooxxoxoxooooo"
val reg = Regex("(?<=x+)|(?=x+)")
var list = str.split(reg)
println(list) 

The output is [, x, x, ooooooo, x, x, o, x, o, x, ooooo], though I would like to get

[xx, ooooooo, xx, o, x, o, x, ooooo]

2 Answers
val str = "xxoooooooxxoxoxooooo"
val reg =  Regex("o+|x+").findAll(str).map { it.value }.toList()
println(reg)
//[xx, ooooooo, xx, o, x, o, x, ooooo]

Actually, it is not correct to use + quantifier inside a lookbehind in Java's regex patterns, this is not a documented supported feature. It does not throw exception because internally it is translated into {1,0x7FFFFFFF} and Java's regex supports constrained-width lookbehind patterns. However, this quantifier in both the lookbehind and lookahead makes no difference as these are non-consuming patterns, and the regex engine still checks each position inside a string for a pattern match.

You can use

(?<=x)(?=o)|(?<=o)(?=x)

See a Kotlin demo:

val str = "xxoooooooxxoxoxooooo"
val reg = Regex("(?<=x)(?=o)|(?<=o)(?=x)")
var list = str.split(reg)
println(list) 
// => [xx, ooooooo, xx, o, x, o, x, ooooo]
Related