(system-include "carp_pattern.h") (defmodule Pattern (doc find "Finds the index of a pattern in a string. Returns -1 otherwise.") (register find (Fn [&Pattern &String] Int)) (doc match "Finds the match groups of the first match of a pattern in a string. Returns [] otherwise.") (register match (Fn [&Pattern &String] (Array String))) (doc match-str "Finds the first match of a pattern in a string. Returns [] otherwise.") (register match-str (Fn [&Pattern &String] String)) (doc global-match "Finds all matches of a pattern in a string as a nested array. Returns [] otherwise.") (register global-match (Fn [&Pattern &String] (Array (Array String)))) (doc substitute "Finds all matches of a pattern in a string and replaces it by another n times (-1 for all occurrences).") (register substitute (Fn [&Pattern &String &String Int] String)) (doc matches? "Checks whether a pattern matches a string.") (defn matches? [pat s] (/= (find pat s) -1)) (register str (Fn [&Pattern] String)) (register prn (Fn [&Pattern] String)) (register init (Fn [&String] Pattern)) (register = (Fn [&Pattern &Pattern] Bool)) (register delete (Fn [Pattern] ())) (register copy (Fn [&Pattern] Pattern)) (doc from-chars "Creates a pattern that matches a group of characters from a list of those characters.") (defn from-chars [chars] (Pattern.init &(string-join @"[" (String.from-chars chars) @"]"))) ) (defmodule String (doc in? "Checks whether a string contains another string.") (defn in? [s sub] (Pattern.matches? &(Pattern.init sub) s)) (doc upper? "Checks whether a string is all uppercase.") (defn upper? [s] (Pattern.matches? #"^[\u\s\p]*$" s)) (doc lower? "Checks whether a string is all lowercase.") (defn lower? [s] (Pattern.matches? #"^[\l\s\p]*$" s)) (doc num? "Checks whether a string is numerical.") (defn num? [s] (Pattern.matches? #"^[0-9]*$" s)) (doc alpha? "Check if a string contains only alpha characters (a-Z).") (defn alpha? [s] (Pattern.matches? #"^[\u\l]*$" s)) (doc alphanum? "Checks whether a string is alphanumerical.") (defn alphanum? [s] (Pattern.matches? #"^[\w]*$" s)) (doc hex? "Checks whether a string is hexadecimal.") (defn hex? [s] (Pattern.matches? #"^[\x]*$" s)) (doc trim-left "Trims whitespace from the left of a string.") (defn trim-left [s] (Pattern.substitute #"^\s+" s "" 1)) (doc trim-right "Trims whitespace from the right of a string.") (defn trim-right [s] (Pattern.substitute #"\s+$" s "" 1)) (doc trim "Trims whitespace from both sides of a string.") (defn trim [s] (trim-left &(trim-right s))) (doc chomp "Trims newline from the end of a string.") (defn chomp [s] (Pattern.substitute #"\n$" s "" 1)) (doc collapse-whitespace "Collapse groups of whitespace into single spaces.") (defn collapse-whitespace [s] (Pattern.substitute #"\s+" s " " -1)) (doc split-by "Split a string by separators.") (defn split-by [_s separators] (let-do [s @_s result (the (Array String) []) pat (Pattern.from-chars separators) idx (Pattern.find &pat &s)] (while (Int./= idx -1) (do (set! result (Array.push-back result (prefix-string &s idx))) (set! s (suffix-string &s (+ idx 1))) (set! idx (Pattern.find &pat &s)))) (Array.push-back result s))) (doc words "Split a string into words.") (defn words [s] (split-by s &[\tab \space])) (doc lines "Split a string into lines.") (defn lines [s] (split-by s &[\newline])) )