I want to be able to check if a Regex matches part...
# announcements
x
I want to be able to check if a Regex matches part of a string starting at a specified offset (and it doesn't need to match until the end of the string).
x
find searches ahead until it finds a match. I want to find a match starting at a certain position, but not necessarily all the way to the end of the string.
For example, given
"foo456bar"
, the Regex
"\\d+"
and the position "3", I'd like it to give me a match on the substring "456".
I can do this with Java's regex stuff by setting the "region" to start at 3, and then using
lookingAt
to tell if my Matcher matches at the start of the region.
m
So are the following equivalent? -
regex.toPattern().matcher(input).region(startIndex, input.length).lookingAt()
-
regex.find(input, startIndex)?.range?.start == startIndex
From what I can tell they are. So you can either use a Kotlin
Regex
and convert it to a
Pattern
and use a
Matcher
which you are already familiar with or you can use
find
with a check on the returned
kotlin.text.MatchResult
.
x
Yes, that's equivalent to
lookingAt
in terms of behavior, but performance would be much worse, since it's going to be constantly trying to match stuff I'm just going to throw away.
I'm currently converting to a
Pattern
and
Matcher
, but was hoping for a more "Kotlin-y" way of doing it.
Thanks for your help.
n
what about the following:
Copy code
fun main(args: Array<String>) {
    println("Hello, world!")
    val input = "foo456bar"
    val p1 = Regex("\\d+")
    println(p1.find(input, 3)?.range?.first == 3)
    val p2 = Regex(".{3}\\d+.+")
    println(p2.matches(input))
}
m
That has the same problem as
...?.start == startIndex
in that
find
will continue searching the entire string for a match where the goal is to only match at that index and avoid the performance impact of searching the entire string unnecessarily.
n
The
p2
approach would not do that because it's anchored but needs to skip over
{n}
read characters every time. I would assume that this is optimized to a seek, and thus comes pretty close to what you want
m
Oh I see. Yeah, that should do it.
x
@nkiesel interesting idea, but seems pretty awkward even compared to having to use Java's Pattern+Matcher. Also, in my case I'm repeatedly searching for the same Regex, but at different positions. Repeatedly modifying the Regex means a lot of regex recompilation. It seems very weird to me that Kotlin's Regex API strips out so much of the capabilities in Java's Pattern/Matcher, unless the toPattern escape hatch is used.