How do I compare strings for fuzzy or approximate matching in EK9?
← Common String Operations · Ref: Q179
EK9 has a built-in Levenshtein distance operator for fuzzy string comparison. The <~> operator returns the edit distance between two strings as an Integer.
LEVENSHTEIN DISTANCE (<~>)
Compute edit distance between two strings:
dist <- str1 <~> str2
Returns the minimum number of single-character edits (insertions, deletions, substitutions) needed to transform one string into the other.
IDENTICAL STRINGS
"hello" <~> "hello" returns 0
SINGLE EDIT
"kitten" <~> "sitten" returns 1 (one substitution)
PRACTICAL USE: TYPO DETECTION
Use a threshold to detect likely typos:
if (input <~> expected) <= 2 stdout.println("Close enough")
REGEX FOR PATTERN MATCHING
For pattern-based matching rather than distance:
if myString matches /pattern/
See Q37 for string basics. See Q33 for regular expressions.
See Q37 for strings. See Q33 for regular expressions. See Q239 for the <~> fuzzy comparison operator used in ordering and matching.
Example
defines module qa.stringops.fuzzymatch defines program FuzzyMatchDemo() stdout <- Stdout() // === LEVENSHTEIN DISTANCE (<~>) === // Identical strings — distance 0 greeting <- "hello" sameGreeting <- "hello" dist0 <- greeting <~> sameGreeting stdout.println(`hello <~> hello = ${dist0}`) // One substitution — distance 1 original <- "kitten" dist1 <- original <~> "sitten" stdout.println(`kitten <~> sitten = ${dist1}`) // Multiple edits dist3 <- original <~> "sitting" stdout.println(`kitten <~> sitting = ${dist3}`) // Empty string planet <- "world" distEmpty <- planet <~> "" stdout.println(`world <~> empty = ${distEmpty}`) // === PRACTICAL: TYPO DETECTION === expected <- "function" typo <- "funciton" typoDistance <- expected <~> typo stdout.println(`Typo distance: ${typoDistance}`) typoThreshold <- 2 if typoDistance <= typoThreshold stdout.println("Close enough - likely a typo") // === PRACTICAL: FIND CLOSEST MATCH === input <- "colr" target1 <- "color" target2 <- "collar" target3 <- "column" d1 <- input <~> target1 d2 <- input <~> target2 d3 <- input <~> target3 stdout.println(`colr <~> color = ${d1}`) stdout.println(`colr <~> collar = ${d2}`) stdout.println(`colr <~> column = ${d3}`) // === REGEX FOR PATTERN MATCHING === testPhrase <- "Hello World" if testPhrase matches /.*World$/ stdout.println("Pattern match: ends with World")
Common mistakes
E50060 — String has no levenshtein() method. Use the <~> operator for Levenshtein distance. See ek9 -h E50060 for details.
Incorrect:
dist1 <- original.levenshtein("sitten")
Correct:
dist1 <- original <~> "sitten"
Other ways to ask this
- Does EK9 have Levenshtein distance?
- How do I find similar strings in EK9?
- How do I detect typos or approximate matches in EK9?
Coming from another language?
Java: no built-in Levenshtein, requires Apache Commons or custom implementation. Python: no built-in, requires python-Levenshtein or difflib.SequenceMatcher. Rust: no built-in, requires strsim crate. Go: no built-in, requires third-party packages. JavaScript: no built-in, requires libraries. Kotlin: no built-in. EK9: built-in <~> operator returns Levenshtein distance as Integer, no libraries needed.
Keywords: text, match, approximate, string, typo, compare, similar, levenshtein, fuzzy, regex, distance