How do I replace or transform text in a string in EK9?
← Common String Operations · Ref: Q175
String has a replace() method, but it takes a RegEx (not a String) as the pattern: replace(with as RegEx, replacement as String). It replaces EVERY match, and the replacement can refer to capture groups as $1, $2. For other transformations, use split + stream rejoin, or stream the characters through map/filter.
REPLACE WITH A REGEX
spaced <- csv.replace(/,/, " ") // "Alice Bob Charlie" masked <- code.replace(/[0-9]+/, "#") // "a1b22c333" becomes "a#b#c#"
Passing a String as the pattern (csv.replace(",", " ")) does not compile: there is no replace() that takes a String.
SPLIT AND REJOIN
Break at a pattern and collect back together:
parts <- sentence.split(/,/)
Split returns a List of String. Rejoin the parts using stream collect:
rejoined <- cat parts | collect as String
CHARACTER STREAMING
Strings are streamable as character sequences. Transform each character:
cat myString | map with toUpper | collect as String
Filter out specific characters:
cat myString | filter by isNotSpace | collect as String
WHEN TO STREAM INSTEAD
Strings are streamable sequences of characters, so per-character rules (upper-case each one, keep only letters) are a map or filter stage rather than a pattern.
See Q37 for string streaming. See Q33 for regular expressions. See Q89 for stream pipelines.
Example
defines module qa.stringops.transform defines function isNotComma() as pure -> ch as Character <- rtn as Boolean: ch <> ',' charToUpper() as pure -> ch as Character <- rtn as String: $ch.upperCase() isLetter() as pure -> ch as Character <- rtn as Boolean: $ch matches /[A-Za-z]/ defines program StringTransformDemo() stdout <- Stdout() // === REPLACE WITH A REGEX === csv <- "Alice,Bob,Charlie" spaced <- csv.replace(/,/, " ") stdout.println(`Replaced: ${spaced}`) // Every match is replaced, not only the first code <- "a1b22c333" masked <- code.replace(/[0-9]+/, "#") stdout.println(`Masked: ${masked}`) // === SPLIT AND REJOIN === parts <- csv.split(/,/) stdout.println(`Split: ${parts}`) // Rejoin without commas rejoined <- cat parts | collect as String stdout.println(`Rejoined: ${rejoined}`) // === CHARACTER STREAMING — FILTER === // Remove commas by filtering characters noCommas <- cat csv | filter by isNotComma | collect as String stdout.println(`No commas: ${noCommas}`) // === CHARACTER STREAMING — MAP === // Transform to uppercase via character stream lower <- "hello world" upper <- cat lower | map with charToUpper | collect as String stdout.println(`Uppercased via stream: ${upper}`) // === EXTRACT ONLY LETTERS === messy <- "h3ll0 w0rld!" lettersOnly <- cat messy | filter by isLetter | collect as String stdout.println(`Letters only: ${lettersOnly}`) // === SPLIT WITH REGEX === sentence <- "one two three" words <- sentence.split(/ +/) stdout.println(`Words: ${words}`)
Common mistakes
E50060 — String.replace() takes a RegEx as its pattern, not a String, so there is no replace() matching (String, String). Write the pattern as a regex literal: /,/. See ek9 -h E50060 for details.
Incorrect:
spaced <- csv.replace(",", " ")
Correct:
spaced <- csv.replace(/,/, " ")
Other ways to ask this
- Does EK9 have a string replace method?
- How do I substitute text in a string in EK9?
- How do I transform characters in a string in EK9?
Coming from another language?
Java: str.replace(), str.replaceAll(regex). Python: str.replace(), re.sub(). Rust: str.replace(), str.replacen(). Go: strings.Replace(), strings.ReplaceAll(). JavaScript: str.replace(), str.replaceAll(). Kotlin: str.replace(), str.replace(regex). EK9: str.replace(/regex/, replacement) replaces every match (like Java's replaceAll) - the pattern must be a RegEx literal, not a String; or split(regex) + collect, or stream characters with map/filter.
Keywords: text, map, string, split, replace, substitute, characters, stream, filter, regex, transform