skip to content

How do you create a Regex in Kotlin and check whether a string contains a match versus matches the whole input? Contrast matchEntire, find, and containsMatchIn.

level: juniorimportance: must knowfreq 70%

answer

  1. Regex(...) or "...".toRegex()
  2. containsMatchIn = anywhere (Boolean)
  3. find = first MatchResult?
  4. matchEntire/matches = whole string
  5. compile once, reuse

basics

~10 s

Make a Regex with Regex("...") or "...".toRegex(). Use containsMatchIn to see if a match appears anywhere, find to get the first match, and matchEntire when the whole string must match the pattern.

solid answer

~30 s

You build a pattern with the Regex(pattern) constructor or the String.toRegex() extension. To test it: containsMatchIn(input) returns a Boolean for 'is there a match anywhere'; find(input) returns the first MatchResult? (null if none) and supports a startIndex; matchEntire(input) returns a MatchResult? only if the ENTIRE input matches; and matches(input) is the Boolean form of matchEntire. Don't confuse partial vs full matching: "\\d+".toRegex().containsMatchIn("a1b") is true, but matchEntire("a1b") is null because letters surround the digit. Regex compilation is relatively expensive, so create the Regex once (e.g. a top-level val) and reuse it rather than recompiling per call.

code

kotlin · 5 lines
kotlin
val number = Regex("\\d+")

fun isAllDigits(s: String) = number.matches(s)        // whole string
fun hasDigit(s: String) = number.containsMatchIn(s)    // anywhere
fun firstNumber(s: String): String? = number.find(s)?.value

go deeper

for a junior

Knows how to construct a Regex and pick containsMatchIn vs matches for a basic 'contains' or 'validate' task.

for a middle

Articulates the partial-vs-full distinction, the nullable MatchResult return types, and the implicit anchoring of matches/matchEntire.

for a senior

Adds performance/thread-safety reasoning (compile once, immutable, reusable) and avoids the validation anti-pattern.

for a principal

Frames Regex choice in terms of API contracts and correctness risk, and reasons about when a parser/non-regex approach is safer than regex validation.

## Creating a Regex Kotlin's `kotlin.text.Regex` wraps the JVM's `java.util.regex.Pattern`. Two equivalent ways to build one: ```kotlin val r1 = Regex("\\d+") // constructor val r2 = "\\d+".toRegex() // String extension ``` Both take an optional `RegexOption` (e.g. `RegexOption.IGNORE_CASE`). Because compiling a pattern is comparatively costly, declare a `Regex` **once** (top-level `val`, companion, or property) and reuse it instead of constructing it inside a hot loop. ## Testing functions — partial vs full match - **`containsMatchIn(input): Boolean`** — true if the pattern matches *anywhere* in the input (a partial/unanchored search). This is what you want for "does this text contain a number?". - **`find(input, startIndex = 0): MatchResult?`** — returns the *first* match as a `MatchResult`, or `null`. Gives you position/value, not just a boolean. - **`matchEntire(input): MatchResult?`** — returns a `MatchResult` only if the **whole** input matches end to end; otherwise `null`. - **`matches(input): Boolean`** — boolean equivalent of `matchEntire`; in Kotlin you can also write `input matches regex` via the infix `String.matches`. ```kotlin val digits = Regex("\\d+") digits.containsMatchIn("a1b") // true (partial) digits.find("a1b")?.value // "1" digits.matchEntire("a1b") // null (letters around it) digits.matchEntire("123")?.value // "123" digits.matches("123") // true ``` ## Key gotcha: anchoring Unlike some languages, Kotlin/Java `matches`/`matchEntire` implicitly require the *entire* string to match — you do NOT need to add `^...$`. Conversely `find`/`containsMatchIn` are unanchored. Choosing the wrong one is the classic validation bug (e.g. accepting `"123abc"` as a number because you used `containsMatchIn`).

  • Why prefer a top-level val Regex over constructing it inside a function called in a loop?
    Compiling the pattern is expensive; reusing one immutable, thread-safe Regex avoids recompiling on every call and reduces allocation.
  • Does matches require ^ and $ anchors?
    No. matches/matchEntire already require the entire input to match, so explicit anchors are redundant.

containsMatchIn is asking 'is this word somewhere in the page?'; matchEntire is asking 'is the page exactly this one word?'.

saying these in an interview costs you the question

  • Using containsMatchIn for validation that should match the whole string
  • Thinking matchEntire returns a Boolean (it returns MatchResult?)
  • Recompiling Regex inside a loop or per request
  • Forgetting to escape backslashes (\\d) in a plain string literal
  • Believing find returns all matches

context