1. Introduction

Regular expressions are notoriously complex to get right, but on the other hand, they are irreplaceable in many string manipulations. Kotlin provides easy access to regular expression functionality while trying to make its usage simpler than the Java standard library.

There were some changes in the Regex class in Kotlin version 1.7, which we’ll look at in this tutorial.

2. Regular Expressions in Kotlin

Since Kotlin is interoperable with Java libraries, we can, of course, use java.util.regex.* package if we run our application in JVM. However, Kotlin now has a Javascript transpiler and also produces a native binary for better support of embedded environments. In that case, we won’t be able to access the Java standard library.

Another reason to prefer Kotlin API instead of Java is that Java API represents a somewhat old-fashioned approach to regular expression matching. It’s more verbose and feels awkward, as we need to create both Pattern and Matcher to test a string:

val regex = "The"
val stringToBeMatched = "The quick brown fox"
assert(Pattern.compile(regex).matcher(stringToBeMatched).lookingAt())

Compare that with the simplicity of Kotlin expression, where a string can become an empowered Regex that knows by itself how to match against a string:

assert("The".toRegex().find("The quick brown fox") != null)

However, Regex doesn’t wrap every aspect of Java’s standard library. For example, one thing that was missing for a long time was the ability to start matching at a specific index.

3. Matching Regular Expression at a Specific Index

There could be several use cases for a Regex match. First of all, we may be asking if our pattern is inside the string at all. Another case will be to ensure that the string starting character sequence matches our pattern. And finally, generalizing the second case, we might be looking for a match at a specific place in the string:

val stringToBeMatched = "The quick brown fox"
val versionRegex = "f.x".toRegex()
assert(versionRegex.matchesAt(stringToBeMatched, 0))
assert(!versionRegex.matchesAt(stringToBeMatched, 16))

The two functions that allow these operations are matchesAt() and matchAt(). The first one returns the answer to the question: “Does the expression match at the position index?” while the second one answers to: “what is the match at the index?”. This functionality was under an experimental flag since 1.5 and was finally released in 1.7.

It’s useful when our String is a sequence of tokens, and we don’t want to split it before finding the match for more efficient memory use:

val actualUrl = "jdbc:postgresql://example.cs945smhrv09.us-west-2.rds.amazonaws.com:5423/ciadb"
val protocolExpression = "jdbc|r2dbc".toRegex()
val protocol = protocolExpression.matchAt(actualUrl, 0)?.value
val rdbmsExpression = "mysql|postgresql|oracle".toRegex()
val rdbms = rdbmsExpression.matchAt(actualUrl, actualUrl.indexOf(':', 0) + 1)?.value
loadDriver(protocol, rdbms)

In the example above, only the strings that matter to further execution are shown.

4. Conclusion

In this article, we looked at the Kotlin Regex class. Kotlin Regex is a useful substitute for Java standard regular expression utilities because it has a terser syntax and is available for Kotlin/Native and Kotlin/JS, as well as for Kotlin/JVM builds. The Regex functions matchAt() and matchesAt() are released as stable in Kotlin 1.7.

They allow us to match a string part to a regular expression starting from a specific position.

All the code, as usual, is in our repository over on GitHub.