Skip to content

Instantly share code, notes, and snippets.

@jeremy-w
Created November 16, 2018 16:13
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeremy-w/3d012dd5051898f09477f443ad1d7bf5 to your computer and use it in GitHub Desktop.
Save jeremy-w/3d012dd5051898f09477f443ad1d7bf5 to your computer and use it in GitHub Desktop.
How do you access a named group in Kotlin?
#!/usr/bin/env kotlinc -script --
/**
@file named-match-repro.kts
@author Jeremy W. Sherman (GitHub: @jeremy-w)
Demo of some perplexing behavior.
Questions:
- Main question: How do I access a named capture group in a Kotlin script?
- Follow-up questions:
- How does the safe-cast to MatchNamedGroupCollection succeed, but then
explode on trying to use the named-group feature?
(see sample log at end of file)
- How is it that the Pattern handles the named group fine, but I can't
actually get the group by name?
Relevant versions:
> kotlinc -version
info: kotlinc-jvm 1.3.0 (JRE 1.8.0_144-b01)
> javac -version
javac 1.8.0_144
> sw_vers
ProductName: Mac OS X
ProductVersion: 10.13.6
BuildVersion: 17G3025
> uname -a
Darwin Eclipse.local 17.7.0 Darwin Kernel Version 17.7.0: Wed Oct 10
23:06:14 PDT 2018; root:xnu-4570.71.13~1/RELEASE_X86_64 x86_64
*/
import kotlin.system.exitProcess
val input = args.firstOrNull() ?: "abc123xyz456"
val numbersRegex = Regex("""(?<number>\d+)""")
val matches = numbersRegex.findAll(input).toList()
println("There are ${matches.size} numbers in \"$input\":")
for (match in matches) {
val numberGroup =
try {
(match.groups as? MatchNamedGroupCollection)?.let {
println("DEBUG: MatchNamedGroupCollection: implementsMatchNamedGroupCollection=${it::class is MatchNamedGroupCollection} it=$it")
println("See that \"false\"? How the heck did that safe-cast succeed?!")
it.get("number")
}
} catch(t: Throwable) {
println("ERROR: NamedGroup failed: $t")
t.printStackTrace()
println("\nFalling back on numbered groups.")
null
}
?:
match.groups.get(1)
numberGroup?.let {
val number = it.value
println("$number")
}
}
/*
Sample run:
> ./named-match-repro.kts abc123
There are 1 numbers in "abc123":
DEBUG: MatchNamedGroupCollection: implementsMatchNamedGroupCollection=false it=[MatchGroup(value=123, range=3..5), MatchGroup(value=123, range=3..5)]
See that "false"? How the heck did that safe-cast succeed?!
ERROR: NamedGroup failed: java.lang.UnsupportedOperationException: Retrieving groups by name is not supported on this platform.
java.lang.UnsupportedOperationException: Retrieving groups by name is not supported on this platform.
at kotlin.internal.PlatformImplementations.getMatchResultNamedGroup(PlatformImplementations.kt:20)
at kotlin.text.MatcherMatchResult$groups$1.get(Regex.kt:290)
at Named_match_repro.<init>(named-match-repro.kts:17)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.jetbrains.kotlin.script.ReflectionUtilKt.tryConstructClassFromStringArgs(reflectionUtil.kt:27)
at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileAndExecuteScript$cli(KotlinToJVMBytecodeCompiler.kt:263)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:182)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:57)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:96)
at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:52)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:93)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:71)
at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:39)
at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit(CLITool.kt:202)
at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMain(CLITool.kt:194)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler$Companion.main(K2JVMCompiler.kt:350)
at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.main(K2JVMCompiler.kt)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jetbrains.kotlin.preloading.Preloader.run(Preloader.java:81)
at org.jetbrains.kotlin.preloading.Preloader.main(Preloader.java:43)
Falling back on numbered groups.
123
*/
@jeremy-w
Copy link
Author

This appears to be a known issue: https://youtrack.jetbrains.com/issue/KT-20865

But there, they're talking about it being broken on Java 9, while I'm running Java 8 at the moment… 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment