diff --git a/libraries/stdlib/jvm/src/kotlin/text/regex/Regex.kt b/libraries/stdlib/jvm/src/kotlin/text/regex/Regex.kt index 144b061ad3a..cade882abee 100644 --- a/libraries/stdlib/jvm/src/kotlin/text/regex/Regex.kt +++ b/libraries/stdlib/jvm/src/kotlin/text/regex/Regex.kt @@ -187,7 +187,23 @@ internal constructor(private val nativePattern: Pattern) : Serializable { @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") public actual fun split(input: CharSequence, limit: Int = 0): List { require(limit >= 0, { "Limit must be non-negative, but was $limit." }) - return nativePattern.split(input, if (limit == 0) -1 else limit).asList() + + val matcher = nativePattern.matcher(input) + if (!matcher.find() || limit == 1) return listOf(input.toString()) + + val result = ArrayList(if (limit > 0) limit.coerceAtMost(10) else 10) + var lastStart = 0 + val lastSplit = limit - 1 // negative if there's no limit + + do { + result.add(input.substring(lastStart, matcher.start())) + lastStart = matcher.end() + if (lastSplit >= 0 && result.size == lastSplit) break + } while (matcher.find()) + + result.add(input.substring(lastStart, input.length)) + + return result } /** Returns the string representation of this regular expression, namely the [pattern] of this regular expression. */ diff --git a/libraries/stdlib/test/text/RegexTest.kt b/libraries/stdlib/test/text/RegexTest.kt index e2160a33682..d07c4a4b692 100644 --- a/libraries/stdlib/test/text/RegexTest.kt +++ b/libraries/stdlib/test/text/RegexTest.kt @@ -203,6 +203,24 @@ class RegexTest { } + @Test fun splitByEmptyMatch() { + val input = "test" + + val emptyMatch = "".toRegex() + + assertEquals(input.split(""), input.split(emptyMatch)) + assertEquals(input.split("", limit = 3), input.split(emptyMatch, limit = 3)) + + assertEquals("".split(""), "".split(emptyMatch)) + + val emptyMatchBeforeT = "(?=t)".toRegex() + + assertEquals(listOf("", "tes", "t"), input.split(emptyMatchBeforeT)) + assertEquals(listOf("", "test"), input.split(emptyMatchBeforeT, limit = 2)) + + assertEquals(listOf("", "tee"), "tee".split(emptyMatchBeforeT)) + } + } \ No newline at end of file