Skip to content

Commit

Permalink
Revert using regex Pattern in String.replace
Browse files Browse the repository at this point in the history
Use String.indexOf(..., ignoreCase) instead in all branches to preserve
compatibility with behavior before 1.4.20 that used String.split which
essentially relied on that String.indexOf

#KT-43745 Fixed

(cherry picked from commit 149bcc2)
  • Loading branch information
ilya-g committed Dec 4, 2020
1 parent cb93152 commit a3b1456
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 11 deletions.
12 changes: 1 addition & 11 deletions libraries/stdlib/jvm/src/kotlin/text/StringsJVM.kt
Expand Up @@ -77,17 +77,7 @@ public actual fun String.replace(oldChar: Char, newChar: Char, ignoreCase: Boole
*/
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun String.replace(oldValue: String, newValue: String, ignoreCase: Boolean = false): String {
if (ignoreCase) {
val matcher = Pattern.compile(oldValue, Pattern.LITERAL or Pattern.CASE_INSENSITIVE).matcher(this)
if (!matcher.find()) return this
val stringBuilder = StringBuilder()
var i = 0
do {
stringBuilder.append(this, i, matcher.start()).append(newValue)
i = matcher.end()
} while (matcher.find())
return stringBuilder.append(this, i, length).toString()
} else {
run {
var occurrenceIndex: Int = indexOf(oldValue, 0, ignoreCase)
// FAST PATH: no match
if (occurrenceIndex < 0) return this
Expand Down
16 changes: 16 additions & 0 deletions libraries/stdlib/test/text/StringTest.kt
Expand Up @@ -896,6 +896,22 @@ class StringTest {

assertEquals("-a-b-b-A-b-", input.replace("", "-"))
assertEquals("-a-b-b-A-b-", input.replace("", "-", ignoreCase = true))

fun testIgnoreCase(chars: String) {
for ((i, c) in chars.withIndex()) {
val message = "Char: $c (${c.toInt()})"
val expectOneReplaced = chars.replaceRange(i..i, "_")
val expectAllReplaced = "_".repeat(chars.length)
assertEquals(expectOneReplaced, chars.replace(c, '_'), message)
assertEquals(expectAllReplaced, chars.replace(c, '_', ignoreCase = true), "$message, ignoreCase")
assertEquals(expectOneReplaced, chars.replace(c.toString(), "_"), "$message, as string")
assertEquals(expectAllReplaced, chars.replace(c.toString(), "_", ignoreCase = true), "$message, as string, ignoreCase")
}
}

testIgnoreCase("üÜ")
testIgnoreCase("öÖ")
testIgnoreCase("äÄ")
}

@Test fun replaceFirst() {
Expand Down

0 comments on commit a3b1456

Please sign in to comment.