Coder Social home page Coder Social logo

cl-str's Introduction

A modern and consistent Common Lisp string manipulation library

(ql:quickload "str")

Why ?

  • modernity, simplicity and discoverability:

    • (str:trim s) instead of (string-trim '(#\Space #\Newline #\Backspace #\Tab #\Linefeed #\Page #\Return #\Rubout) s)), or str:concat strings instead of an unusual format construct; one discoverable library instead of many;
  • consistance and composability, where s is always the last argument, which makes it easier to feed pipes and arrows.

The only dependency is cl-ppcre.

Table of Contents

Install

Install with Quicklisp:

(ql:quickload :str)

Check its version:

(str:version)

To get a newer version, you need to update the Quicklisp dist (think of QL as Debian's apt rather than pip/npm/etc):

(ql:update-dist "quicklisp")

beware, this is a young and unstable library. (update v0.7) The functions implementation may change, but we shouldn't change the api.

(don't have a full Common Lisp development environment yet ? Get Portacle, a portable and multiplatform development environment shipping Emacs, Quicklisp, SBCL and Git).

Functions

Tweak whitespace

trim (s)

Remove whitespaces at the beginning and end of s.

(trim "  rst  ") ;; => "rst"

Also trim-left and trim-right.

Uses the built-in string-trim where whitespaces are '(#\Space #\Newline #\Backspace #\Tab #\Linefeed #\Page #\Return #\Rubout).

To longer strings

join (separator list-of-strings)

Join strings in list list-of-strings with separator in between.

(join " " '("foo" "bar" "baz")) ;; => "foo bar baz"

Uses a specific format syntax.

concat (&rest strings)

Join strings into one.

(concat "f" "o" "o") ;; => "foo"

Simple call of the built-in concatenate.

repeat (count s)

Make a string of s repeated count times.

(repeat 3 "foo") ;; => "foofoofoo"

add-prefix, add-suffix (items s) (new in 0.9)

Respectively prepend or append s to the front of each item.

To shorter strings

substring (start end s)

Return the substring of s from start to end.

It uses subseq with differences:

  • argument order, s at the end
  • start and end can be lower than 0 or bigger than the length of s.
  • for convenience end can be nil or t to denote the end of the string.

Examples:

  (is "abcd" (substring 0 t "abcd") "t denotes the end of the string")
  (is "abcd" (substring 0 nil "abcd") "nil too")
  (is "abcd" (substring 0 100 "abcd") "end can be too large")
  (is "abc" (substring 0 -1 "abcd") "end can be negative. Counts from the end.")
  (is "" (substring 0 -100 "abcd") "end can be negative and too low")
  (is "" (substring 100 1 "abcd") "start can be too big")
  (is "abcd" (substring -100 4 "abcd") "start can also be too low")
  (is "" (substring 2 1 "abcd") "start is bigger than end")

s-first (s)

Return the first letter of s.

Examples:

  (s-first "foobar") ;; => "f"
  (s-first "") ;; => ""

s-rest (s)

Return the rest substring of s.

Examples:

  (s-rest "foobar") ;; => "oobar"
  (s-rest "") ;; => ""

s-nth (n s)

Return the nth letter of s.

Examples:

  (s-nth 3 "foobar") ;; => "b"
  (s-nth 3 "") ;; => ""

To and from lists

words (s)

Return list of words, which were delimited by whitespace.

unwords (strings)

Join the list of strings with a whitespace.

lines (s)

Split string by newline character and return list of lines.

unlines (strings)

Join the list of strings with a newline character.

split (separator s &key omit-nulls)

Split into subtrings (unlike cl-ppcre, without a regexp). If omit-nulls is non-nil, zero-length substrings are omitted.

(split "+" "foo++bar") ;; => ("foo" "" "bar")
(split "+" "foo++bar" :omit-nulls t) ;; => ("foo" "bar")

Wrapper around cl-ppcre:split but:

  • our separator is a simple string, where cl-ppcre takes a regexp,
  • we fix an inconsistency:
(cl-ppcre:split "," ",a,b,,c,") ;; => ("" "a" "b" "" "c")

and we return a trailing "":

(split "," ",a,b,,c,") ;; => ("" "a" "b" "" "c" "")

split-omit-nulls (in v0.6, QL january 2018)

Because it is a common pattern and it can be clearer than an option coming after many parenthesis.

To and from files (experimental in v0.4)

from-file (filename)

Read the file and return its content as a string.

Example: (str:from-file "path/to/file.txt").

:external-format: if nil, the system default. Can be bound to :utf-8.

But you might just call uiop's uiop:read-file-string directly.

There is also uiop:read-file-lines.

to-file (filename s)

Write the string s to the file filename. If the file does not exist, create it, if it already exists, replace it.

Options:

  • :if-does-not-exist: :create (default), :error
  • :if-exists: :supersede (default), :append, :overwrite, :rename, :error,...

Returns the string written to file.

Predicates

empty?, emptyp (s)

True if s is nil or the empty string:

  (empty? nil) ;; => T
  (empty? "")  ;; => T
  (empty? " ") ;; => NIL

blank?, blankp (s)

True if s is empty or only contains whitespaces.

(blankp "") ;; => T
(blankp " ") ;; => T
(emptyp " ") ;; => NIL

starts-with?, starts-with-p (start s &key ignore-case)

True if s starts with the substring start, nil otherwise. Ignore case by default.

(starts-with? "foo" "foobar") ;; => T
(starts-with? "FOO" "foobar") ;; => NIL
(starts-with? "FOO" "foobar" :ignore-case t) ;; => T

Calls string= or string-equal depending on the case, with their :start and :end delimiters.

ends-with?, ends-with-p (end s &key ignore-case)

True if s ends with the substring end. Ignore case by default.

(ends-with? "bar" "foobar") ;; => T

contains?, containsp (substring s &key (ignore-case nil))

Return true if s contains substring, nil otherwise. Ignore the case with :ignore-case t (don't ignore by default).

Based on a simple call to the built-in search (which returns the position of the substring).

prefix?, prefixp and suffix?, suffixp (items s) (new in 0.9)

Return s if it is a common prefix (or suffix) between items.

Others

replace-all (old new s)

Replace old by new (no regexs) in s.

(replace-all "a" "o" "faa") ;; => "foo"

Uses cl-ppcre:regex-replace-all but quotes the user input to not treat it as a regex.

prefix (list-of-strings) (renamed in 0.9)

(renamed from common-prefix in v0.9)

Find the common prefix between strings.

Example: (str:prefix '(\"foobar\" \"foozz\")) => "foo"

Uses the built-in mismatch, that returns the position at which the strings fail to match.

Return a string or nil when the input is the void list.

suffix (list-of-strings) (new in 0.9)

Find the common suffix between strings.

Macros

string-case (new in v0.8, Quicklisp end of february 2018)

A case-like macro that works with strings (CL's case only works with symbols).

Example:

(str:string-case input
  ("foo" (do something))
  (nil (print "input is nil")
  (otherwise (print "non of the previous forms was caught.")))

You might also like pattern matching. The example below with optima is very similar:

(optima:match "hey"
  ("hey" (print "it matched"))
  (otherwise :nothing))

Note that there is also http://quickdocs.org/string-case/.

Changelog

  • 0.9 (Quicklisp end of may, 2018)
    • added s-first , s-rest and s-nth
    • added prefix and suffix functions and predicates.
  • 0.8 added string-case
  • 0.7 added version
  • 0.6 added split-omit-nulls (QL, january 2018)
  • 0.5 added common-prefix
  • 0.4 added from-file and to-file.
  • 0.3 added substring.

Dev and test

Test with prove.

See also

  • cl-strings, a similar (discovered afterwards), maybe more complete library, that does not use established libraries as dependencies as we do (with potential implementation issues).
  • cl-change-case to convert strings between camelCase, param-case, snake_case and more.
  • the Common Lisp Cookbook, strings page.

Inspired by the famous Emacs Lisp's s.el.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.