diff --git a/libraries/stdlib/src/kotlin/StringsJVM.kt b/libraries/stdlib/src/kotlin/StringsJVM.kt index d3e159ff534..471a7ec1772 100644 --- a/libraries/stdlib/src/kotlin/StringsJVM.kt +++ b/libraries/stdlib/src/kotlin/StringsJVM.kt @@ -524,3 +524,29 @@ public inline fun String.trimTrailing(): String { } return if (count < this.length) substring(0, count) else this } + +/** + * Replaces every *regexp* occurence in the text with the value retruned by the given function *body* that can handle + * particular occurance using [[MatchResult]] provided. + */ +public fun String.replaceAll(regexp: String, body: (java.util.regex.MatchResult) -> String) : String { + val sb = StringBuilder(this.length()) + val p = regexp.toRegex() + val m = p.matcher(this) + + var lastIdx = 0 + while (m.find()) { + sb.append(this, lastIdx, m.start()) + sb.append(body(m.toMatchResult())) + lastIdx = m.end() + } + + if (lastIdx == 0) { + return this; + } + + sb.append(this, lastIdx, this.length()) + + return sb.toString() +} + diff --git a/libraries/stdlib/test/StringJVMTest.kt b/libraries/stdlib/test/StringJVMTest.kt index c607b40e91c..bc6c9e474b1 100644 --- a/libraries/stdlib/test/StringJVMTest.kt +++ b/libraries/stdlib/test/StringJVMTest.kt @@ -295,4 +295,37 @@ class StringJVMTest { assertEquals(s.toByteArray().toString(), s.toByteArray(defaultCharset).toString()) assertEquals(s.toByteArray().toString(), s.toByteArray(defaultCharset.name()).toString()) } + + test fun testReplaceAllClosure() { + val s = "test123zzz" + val result = s.replaceAll("\\d+") { (mr) -> + "[" + mr.group() + "]" + } + assertEquals("test[123]zzz", result) + } + + test fun testReplaceAllClosureAtStart() { + val s = "123zzz" + val result = s.replaceAll("\\d+") { (mr) -> + "[" + mr.group() + "]" + } + assertEquals("[123]zzz", result) + } + + test fun testReplaceAllClosureAtEnd() { + val s = "test123" + val result = s.replaceAll("\\d+") { (mr) -> + "[" + mr.group() + "]" + } + assertEquals("test[123]", result) + } + + test fun testReplaceAllClosureEmpty() { + val s = "" + val result = s.replaceAll("\\d+") { (mr) -> + "x" + } + assertEquals("", result) + + } }