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