All chapters21
On this page

Guide · Chapter 5

Text, JSON, and CSV

Process UTF-8 text, regular expressions, and structured data.

String and UTF-8

String is an immutable UTF-8 byte sequence. length counts Unicode code points, byte_length counts encoded bytes, and indexing returns a one-code-point String. Text functions return new values and never mutate the original.

example.hhy
let line = "  ERROR: timeout  "

line
    |> trim
    |> replace("ERROR", "WARN")
    |> lower
    |> print

functrim#

trim(String) -> String

Remove whitespace from both ends of a String.

funcsplit#

split(String, String) -> List<String>

Split a String by delimiter text into List<String>.

funcjoin#

join(List<String>, String) -> String

Join List<String> with delimiter text.

funcreplace#

replace(String, String, String) -> String

Return a new String with matching text replaced.

funccontains#

contains(String | List, Value) -> Bool

Test whether a String contains a substring or a List contains an equal value.

funcstarts_with#

starts_with(String, String) -> Bool

Test whether a String starts with the given text.

funcends_with#

ends_with(String, String) -> Bool

Test whether a String ends with the given text.

funclower#

lower(String) -> String

Return a new String converted to Unicode lowercase.

funcupper#

upper(String) -> String

Return a new String converted to Unicode uppercase.

Regex

A Regex literal is /pattern/flags with i (case-insensitive), m (multiline), s (dot matches newline), and u. regex_match returns Bool; regex_captures returns the full match, byte positions, numbered groups, and named captures, or null when unmatched.

JSON type mapping and errors

example.hhy
read_text(path("users.json"))
    |> parse_json
    |> get("users")
    |> stream
    |> where { user -> user.active == true }
    |> collect
    |> encode_json({ pretty: true })
    |> save_text(path("active-users.json"))
JSONHHY
objectMap
arrayList
stringString
integerInt
decimalFloat
true / falseBool
nullNull

parse_json reports line and column on failure. encode_json accepts { pretty: true } for readable output. Function, Stream, and system objects require mapping to ordinary fields first.

CSV is a record stream

parse_csv accepts a complete String or Stream<String> and returns Stream<Map>; encode_csv accepts Stream<Map> and returns Stream<String> records without terminators. Neither requires a whole-file buffer.

example.hhy
read_lines(path("employees.csv"))
    |> parse_csv({ header: true })
    |> where { row -> row.active == "true" }
    |> encode_csv({ header: true })
    |> save_lines(path("active-employees.csv"))

header controls field names; delimiter and quote must be single characters. CSV performs no schema inference, so numbers and Bools require explicit conversion. encode_csv omits terminators and composes with save_lines.

Look up the complete API

Text and structured data API Reference →Look up complete signatures for text, Regex, JSON, and CSV functions.