[JS] Support named capture groups in Regex #KT-51775
This commit is contained in:
committed by
Space
parent
cf79752c14
commit
c3f5d03b36
@@ -155,6 +155,68 @@ class RegexTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun matchNamedGroups() {
|
||||
val regex = "\\b(?<city>[A-Za-z\\s]+),\\s(?<state>[A-Z]{2}):\\s(?<areaCode>[0-9]{3})\\b".toRegex()
|
||||
val input = "Coordinates: Austin, TX: 123"
|
||||
|
||||
regex.find(input)!!.let { match ->
|
||||
assertEquals(listOf("Austin, TX: 123", "Austin", "TX", "123"), match.groupValues)
|
||||
|
||||
if (supportsNamedCapturingGroup) {
|
||||
val namedGroups = match.groups as MatchNamedGroupCollection
|
||||
assertEquals(4, namedGroups.size)
|
||||
assertEquals("Austin", namedGroups["city"]?.value)
|
||||
assertEquals("TX", namedGroups["state"]?.value)
|
||||
assertEquals("123", namedGroups["areaCode"]?.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun matchOptionalNamedGroup() {
|
||||
if (!supportsNamedCapturingGroup) return
|
||||
|
||||
"(?<hi>hi)|(?<bye>bye)".toRegex(RegexOption.IGNORE_CASE).let { regex ->
|
||||
val hiMatch = regex.find("Hi!")!!
|
||||
val hiGroups = hiMatch.groups as MatchNamedGroupCollection
|
||||
assertEquals(3, hiGroups.size)
|
||||
assertEquals("Hi", hiGroups["hi"]?.value)
|
||||
assertEquals(null, hiGroups["bye"])
|
||||
assertFailsWith<IllegalArgumentException> { hiGroups["hello"] }
|
||||
|
||||
val byeMatch = regex.find("bye...")!!
|
||||
val byeGroups = byeMatch.groups as MatchNamedGroupCollection
|
||||
assertEquals(3, byeGroups.size)
|
||||
assertEquals(null, byeGroups["hi"])
|
||||
assertEquals("bye", byeGroups["bye"]?.value)
|
||||
assertFailsWith<IllegalArgumentException> { byeGroups["goodbye"] }
|
||||
}
|
||||
|
||||
"(?<hi>hi)|bye".toRegex(RegexOption.IGNORE_CASE).let { regex ->
|
||||
val hiMatch = regex.find("Hi!")!!
|
||||
val hiGroups = hiMatch.groups as MatchNamedGroupCollection
|
||||
assertEquals(2, hiGroups.size)
|
||||
assertEquals("Hi", hiGroups["hi"]?.value)
|
||||
assertFailsWith<IllegalArgumentException> { hiGroups["bye"] }
|
||||
|
||||
// Named group collection consisting of a single 'null' group value
|
||||
val byeMatch = regex.find("bye...")!!
|
||||
val byeGroups = byeMatch.groups as MatchNamedGroupCollection
|
||||
assertEquals(2, byeGroups.size)
|
||||
assertEquals(null, byeGroups["hi"])
|
||||
assertFailsWith<IllegalArgumentException> { byeGroups["bye"] }
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun matchWithBackReference() {
|
||||
val regex = "(?<title>\\w+), yes \\k<title>".toRegex()
|
||||
|
||||
val match = regex.find("Do you copy? Sir, yes Sir!")!!
|
||||
assertEquals("Sir, yes Sir", match.value)
|
||||
assertEquals("Sir", (match.groups as MatchNamedGroupCollection)["title"]?.value)
|
||||
|
||||
assertNull(regex.find("Do you copy? Sir, yes I do!"))
|
||||
}
|
||||
|
||||
@Test fun matchMultiline() {
|
||||
val regex = "^[a-z]*$".toRegex(setOf(RegexOption.IGNORE_CASE, RegexOption.MULTILINE))
|
||||
val matchedValues = regex.findAll("test\n\nLine").map { it.value }.toList()
|
||||
@@ -298,7 +360,7 @@ class RegexTest {
|
||||
"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
|
||||
// take the 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
|
||||
@@ -308,6 +370,11 @@ class RegexTest {
|
||||
// missing trailing '}'
|
||||
assertFailsWith<IllegalArgumentException>("\${first+\${second}") { pattern.replace(input, "\${first+\${second}") }
|
||||
assertFailsWith<IllegalArgumentException>("\${first}+\${second") { pattern.replace(input, "\${first}+\${second") }
|
||||
|
||||
// non-existent group name
|
||||
assertFailsWith<IllegalArgumentException>("\${first}+\${second}+\$third") {
|
||||
pattern.replace(input, "\${first}+\${second}+\$third")
|
||||
}
|
||||
}
|
||||
|
||||
"123-456-789-012".let { input ->
|
||||
@@ -317,6 +384,18 @@ class RegexTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test fun replaceWithNamedOptionalGroups() {
|
||||
if (!supportsNamedCapturingGroup) return
|
||||
|
||||
val regex = "(?<hi>hi)|(?<bye>bye)".toRegex(RegexOption.IGNORE_CASE)
|
||||
|
||||
assertEquals("[Hi, ]gh wall", regex.replace("High wall", "[$1, $2]"))
|
||||
assertEquals("[Hi, ]gh wall", regex.replace("High wall", "[\${hi}, \${bye}]"))
|
||||
|
||||
assertEquals("Good[, bye], Mr. Holmes", regex.replace("Goodbye, Mr. Holmes", "[$1, $2]"))
|
||||
assertEquals("Good[, bye], Mr. Holmes", regex.replace("Goodbye, Mr. Holmes", "[\${hi}, \${bye}]"))
|
||||
}
|
||||
|
||||
@Test fun replaceEvaluator() {
|
||||
val input = "/12/456/7890/"
|
||||
val pattern = "\\d+".toRegex()
|
||||
|
||||
Reference in New Issue
Block a user