Kotlin正则表达式支持命名分组

26

Kotlin是否支持命名正则表达式组?

命名的正则表达式组长这个样子:(?<name>...)

6个回答

32

7
截至 Kotlin 1.0 版本,由于标准库只能使用 JDK6 中可用的 regex api,而该版本不支持命名组,因此 Regex 类目前没有提供访问 MatchGroupCollection 中匹配命名组的方法。
如果您的目标是 JDK8,则可以使用 java.util.regex.Patternjava.util.regex.Matcher 类。后者提供了 group 方法来获取命名捕获组匹配结果。

4
从 Kotlin 1.4 开始,你需要将 groups 的结果转换为 MatchNamedGroupCollection
val groups = """(\w+?)(?<num>\d+)""".toRegex().matchEntire("area51")!!.groups as? MatchNamedGroupCollection 
if (groups != null) {
    println(groups.get("num")?.value)
}

正如 @Vadzim 正确指出的那样,您必须使用 kotlin-stdlib-jdk8 而不是 kotlin-stdlib

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
}

这里有一个关于此的好解释。


1
上面的答案对我没有用,但是以下方法有效:
val pattern = Pattern.compile("""(\w+?)(?<num>\d+)""")
val matcher = pattern.matcher("area51")

while (matcher.find()) {
    val result = matcher.group("num")
}

似乎是API 16及以上版本。有没有适用于旧版Android的解决方案? - casolorz

0
在 Kotlin 1.9+ 版本中,命名分组现在可以在常用的 stdlib 中使用:
根据 Kotlin 1.8.0 的情况,标准库是针对 JVM 目标 1.8 进行编译的。因此在 1.9.0 版本中,现在有一个 common groups 函数,您可以使用它来按名称检索正则表达式匹配的组内容。当您想要访问属于特定捕获组的正则表达式匹配结果时,这将非常有用。 Kotlin 1.9.0 的新功能(强调原文)
他们提供了一个很好的例子:
fun main() {
    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"

    val match = regex.find(input)!!
    println(match.groups["city"]?.value)
    // Austin
    println(match.groups["state"]?.value)
    // TX
    println(match.groups["areaCode"]?.value)
    // 123
}

0

Kotlin

fun regex(regex: Regex, input: String, group: String): String {
    return regex
        .matchEntire(input)!!
        .groups[group]!!
        .value
}

@Test
fun regex() {
    // given
    val expected = "s3://asdf/qwer"

    val pattern = "[\\s\\S]*Location\\s+(?<s3>[\\w/:_-]+)[\\s\\S]*"
    val input = """
        ...
        ...
        Location    s3://asdf/qwer
        Serde Library    org.apache.hadoop.hive.ql.io.orc.OrcSerde
        InputFormat    org.apache.hadoop.hive.ql.io.orc.OrcInputFormat
        OutputFormat    org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat
    """.trimIndent()
    val group = "s3"

    // when
    val actual = CommonUtil.regex(pattern.toRegex(), input, group)

    // then
    assertEquals(expected, actual)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接