Created
November 16, 2018 16:13
-
-
Save jeremy-w/3d012dd5051898f09477f443ad1d7bf5 to your computer and use it in GitHub Desktop.
How do you access a named group in Kotlin?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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… 🤔