Align JS and JVM behavior of Regex replace function #KT-28378
This commit is contained in:
committed by
Space
parent
5326c875c0
commit
dc2f5eab25
@@ -7,6 +7,7 @@
|
||||
|
||||
package test.text
|
||||
|
||||
import test.supportsNamedCapturingGroup
|
||||
import kotlin.test.*
|
||||
|
||||
class RegexTest {
|
||||
@@ -238,10 +239,78 @@ class RegexTest {
|
||||
@Test fun replace() {
|
||||
val input = "123-456"
|
||||
val pattern = "(\\d+)".toRegex()
|
||||
|
||||
// js String.prototype.replace() inserts a "$"
|
||||
assertFailsWith<IllegalArgumentException>("$$") { pattern.replace(input, "$$") }
|
||||
// js String.prototype.replace() inserts the matched substring
|
||||
assertFailsWith<IllegalArgumentException>("$&") { pattern.replace(input, "$&") }
|
||||
// js String.prototype.replace() inserts the portion of the string that precedes the matched substring
|
||||
assertFailsWith<IllegalArgumentException>("\$`") { pattern.replace(input, "\$`") }
|
||||
// js String.prototype.replace() inserts the portion of the string that follows the matched substring
|
||||
assertFailsWith<IllegalArgumentException>("$'") { pattern.replace(input, "$'") }
|
||||
// js String.prototype.replace() inserts the replacement string as a literal if it refers to a non-existing capturing group
|
||||
assertFailsWith<RuntimeException>("$") { pattern.replace(input, "$") } // should be IAE, however jdk7 throws String IOOBE
|
||||
assertFailsWith<IndexOutOfBoundsException>("$2") { pattern.replace(input, "$2") }
|
||||
assertFailsWith<IllegalArgumentException>("\$name") { pattern.replace(input, "\$name") }
|
||||
assertFailsWith<IllegalArgumentException>("\${name}") { pattern.replace(input, "\${name}") }
|
||||
assertFailsWith<IllegalArgumentException>("$-") { pattern.replace(input, "$-") }
|
||||
|
||||
// inserts "$" literally
|
||||
assertEquals("$-$", pattern.replace(input, "\\$"))
|
||||
// inserts the matched substring
|
||||
assertEquals("(123)-(456)", pattern.replace(input, "($0)"))
|
||||
// inserts the first captured group
|
||||
assertEquals("(123)-(456)", pattern.replace(input, "($1)"))
|
||||
|
||||
assertEquals("$&-$&", pattern.replace(input, Regex.escapeReplacement("$&")))
|
||||
assertEquals("X-456", pattern.replaceFirst(input, "X"))
|
||||
|
||||
val longInput = "0123456789ABC"
|
||||
val longPattern = "0(1(2(3(4(5(6(7(8(9(A(B(C))))))))))))".toRegex()
|
||||
for (groupIndex in 0..12) {
|
||||
assertEquals(longInput.substring(groupIndex), longPattern.replace(longInput, "$$groupIndex"))
|
||||
}
|
||||
assertEquals(longInput.substring(1) + "3", longPattern.replace(longInput, "$13"))
|
||||
|
||||
// KT-38000
|
||||
assertEquals("""\,""", ",".replace("([,])".toRegex(), """\\$1"""))
|
||||
// KT-28378
|
||||
assertEquals("$ 2", "2".replace(Regex("(.+)"), "\\$ $1"))
|
||||
assertEquals("$2", "2".replace(Regex("(.+)"), "\\$$1"))
|
||||
assertFailsWith<IllegalArgumentException> { "2".replace(Regex("(.+)"), "$ $1") }
|
||||
}
|
||||
|
||||
@Test fun replaceWithNamedGroups() {
|
||||
if (!supportsNamedCapturingGroup) {
|
||||
assertFails {
|
||||
val pattern = Regex("(?<first>\\d+)-(?<second>\\d+)")
|
||||
pattern.replace("123-456", "\${first}+\${second}")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val pattern = Regex("(?<first>\\d+)-(?<second>\\d+)")
|
||||
|
||||
"123-456".let { input ->
|
||||
assertEquals("(123-456)", pattern.replace(input, "($0)"))
|
||||
assertEquals("123+456", pattern.replace(input, "$1+$2"))
|
||||
// take largest legal group number reference
|
||||
assertEquals("1230+456", pattern.replace(input, "$10+$2"))
|
||||
assertEquals("123+456", pattern.replace(input, "$01+$2"))
|
||||
// js refers to named capturing groups with "$<name>" syntax
|
||||
assertFailsWith<IllegalArgumentException>("\$<first>+\$<second>") { pattern.replace(input, "\$<first>+\$<second>") }
|
||||
assertEquals("123+456", pattern.replace(input, "\${first}+\${second}"))
|
||||
|
||||
// missing trailing '}'
|
||||
assertFailsWith<IllegalArgumentException>("\${first+\${second}") { pattern.replace(input, "\${first+\${second}") }
|
||||
assertFailsWith<IllegalArgumentException>("\${first}+\${second") { pattern.replace(input, "\${first}+\${second") }
|
||||
}
|
||||
|
||||
"123-456-789-012".let { input ->
|
||||
assertEquals("123/456-789/012", pattern.replace(input, "$1/$2"))
|
||||
assertEquals("123/456-789/012", pattern.replace(input, "\${first}/\${second}"))
|
||||
assertEquals("123/456-789-012", pattern.replaceFirst(input, "\${first}/\${second}"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun replaceEvaluator() {
|
||||
|
||||
Reference in New Issue
Block a user