Fix case-insensitive character-wise comparison KT-45496
- Step 1: add failing tests - Step 2: fix common case insensitive Char.equals - Step 3: fix case insensitive String.equals in K/JS - Step 4: enable unicode case folding in K/JS Regexes and string replacement (KT-45928) - Step 5: fix case insensitive char comparison in K/N in String functions String.replace, equals, compareTo with ignoreCase
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -51,7 +51,7 @@ public actual class Regex actual constructor(pattern: String, options: Set<Regex
|
||||
public actual val pattern: String = pattern
|
||||
/** The set of options that were used to create this regular expression. */
|
||||
public actual val options: Set<RegexOption> = options.toSet()
|
||||
private val nativePattern: RegExp = RegExp(pattern, options.map { it.value }.joinToString(separator = "") + "g")
|
||||
private val nativePattern: RegExp = RegExp(pattern, options.joinToString(separator = "", prefix = "gu") { it.value })
|
||||
|
||||
/** Indicates whether the regular expression matches the entire [input]. */
|
||||
public actual infix fun matches(input: CharSequence): Boolean {
|
||||
@@ -200,7 +200,7 @@ public actual class Regex actual constructor(pattern: String, options: Set<Regex
|
||||
*/
|
||||
public actual fun escapeReplacement(literal: String): String = literal.nativeReplace(replacementEscape, "$$$$")
|
||||
|
||||
private val patternEscape = RegExp("""[-\\^$*+?.()|[\]{}]""", "g")
|
||||
private val patternEscape = RegExp("""[\\^$*+?.()|[\]{}]""", "g")
|
||||
private val replacementEscape = RegExp("""\$""", "g")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -57,12 +57,16 @@ public actual fun CharSequence.isBlank(): Boolean = length == 0 || (if (this is
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
|
||||
public actual fun String?.equals(other: String?, ignoreCase: Boolean = false): Boolean =
|
||||
if (this == null)
|
||||
other == null
|
||||
else if (!ignoreCase)
|
||||
this == other
|
||||
else
|
||||
other != null && this.lowercase() == other.lowercase()
|
||||
when {
|
||||
this == null -> other == null
|
||||
!ignoreCase -> this == other
|
||||
other == null -> false
|
||||
else -> {
|
||||
val thisLower = this.lowercase()
|
||||
val otherLower = other.lowercase()
|
||||
thisLower == otherLower || (thisLower.uppercase() == otherLower.uppercase())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
|
||||
@@ -125,16 +129,16 @@ public actual fun CharSequence.repeat(n: Int): String {
|
||||
|
||||
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
|
||||
public actual fun String.replace(oldValue: String, newValue: String, ignoreCase: Boolean = false): String =
|
||||
nativeReplace(RegExp(Regex.escape(oldValue), if (ignoreCase) "gi" else "g"), Regex.escapeReplacement(newValue))
|
||||
nativeReplace(RegExp(Regex.escape(oldValue), if (ignoreCase) "gui" else "gu"), Regex.escapeReplacement(newValue))
|
||||
|
||||
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
|
||||
public actual fun String.replace(oldChar: Char, newChar: Char, ignoreCase: Boolean = false): String =
|
||||
nativeReplace(RegExp(Regex.escape(oldChar.toString()), if (ignoreCase) "gi" else "g"), newChar.toString())
|
||||
nativeReplace(RegExp(Regex.escape(oldChar.toString()), if (ignoreCase) "gui" else "gu"), newChar.toString())
|
||||
|
||||
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
|
||||
public actual fun String.replaceFirst(oldValue: String, newValue: String, ignoreCase: Boolean = false): String =
|
||||
nativeReplace(RegExp(Regex.escape(oldValue), if (ignoreCase) "i" else ""), Regex.escapeReplacement(newValue))
|
||||
nativeReplace(RegExp(Regex.escape(oldValue), if (ignoreCase) "ui" else "u"), Regex.escapeReplacement(newValue))
|
||||
|
||||
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
|
||||
public actual fun String.replaceFirst(oldChar: Char, newChar: Char, ignoreCase: Boolean = false): String =
|
||||
nativeReplace(RegExp(Regex.escape(oldChar.toString()), if (ignoreCase) "i" else ""), newChar.toString())
|
||||
nativeReplace(RegExp(Regex.escape(oldChar.toString()), if (ignoreCase) "ui" else "u"), newChar.toString())
|
||||
|
||||
Reference in New Issue
Block a user