Home > Net >  Incremental regex matching in Kotlin
Incremental regex matching in Kotlin

Time:07-29

This code snipped searches for the first regex match in a file for which one of the capture groups matches a local variable, and then obtains the value of the other capture group.

Is it possible to write this in an idiomatic, more efficient version which doesn't find all matches up front, but rather matches incrementally, without an explicit loop?

val id = ANCHOR_REGEX.findAll(apiFile.readText())
                     .find { label == it.groups["label"]?.value }
                     ?.let { it.groups["id"]?.value }

CodePudding user response:

Yes, there is. And you've already done it. findAll returns a Sequence<MatchResult>, and just to be extra sure, we can look in the source code and see the implementation ourselves.

public actual fun findAll(input: CharSequence, startIndex: Int = 0): Sequence<MatchResult> {
    if (startIndex < 0 || startIndex > input.length) {
        throw IndexOutOfBoundsException("Start index out of bounds: $startIndex, input length: ${input.length}")
    }
    return generateSequence({ find(input, startIndex) }, MatchResult::next)
}

That's generateSequence from the standard library, which produces lazy iterators whose next element is determined by calling the function repeatedly. find on iterables is also perfectly capable of short-circuiting, so the code you've already written will incrementally find matches until it finds the one you want or exhausts the string.

  • Related