The str Reference Manual

This is the str Reference Manual, version 0.21, generated automatically by Declt version 4.0 beta 2 "William Riker" on Sun Dec 08 17:25:13 2024 GMT+0.

Table of Contents


1 Introduction


2 Systems

The main system appears first, followed by any subsystem dependency.


2.1 str

Modern, consistent and terse Common Lisp string manipulation library.

Maintainer

vindarel <>

Author

vindarel <>

Home Page

https://github.com/vindarel/cl-str

Source Control

(GIT git@github.com:vindarel/cl-str.git)

Bug Tracker

https://github.com/vindarel/cl-str/issues

License

MIT

Long Description

[![Quicklisp](http://quickdocs.org/badge/cl-str.svg)](http://quickdocs.org/cl-str)
# A modern and consistent Common Lisp string manipulation library

(ql:quickload "str")

also on [Ultralisp](http://ultralisp.org/).

Why ?

* modernity, simplicity and discoverability:

- ‘(str:trim s)‘ instead of ‘(string-trim ’(#\Backspace #\Tab #\Linefeed #\Newline #\Vt #\Page #\Return #\Space #\Rubout #\Next-Line #\No-break_space) s))‘,
or ‘str:concat strings‘ instead of an unusual ‘format‘ construct; one discoverable library instead of many;

* consistence and composability, where ‘s‘ is always the last argument, which makes it
easier to feed pipes and arrows.

* fixing built-in surprises: ‘(string-downcase nil‘) => ‘"nil"‘ the string, whereas ‘(str:downcase nil)‘ => ‘nil‘.

The only dependency is ‘cl-ppcre‘.

<!– markdown-toc start - Don’t edit this section. Run M-x markdown-toc-refresh-toc –>
**Table of Contents**

- [A modern and consistent Common Lisp string manipulation library](#a-modern-and-consistent-common-lisp-string-manipulation-library)
- [Install](#install)
- [Global parameters](#global-parameters)
- [Functions](#functions)
- [Tweak whitespace](#tweak-whitespace)
- [trim ‘(s &key (char-bag *whitespaces*))‘](#trim-s-key-char-bag-whitespaces)
- [collapse-whitespaces ‘(s)‘](#collapse-whitespaces-s)
- [To longer strings](#to-longer-strings)
- [join ‘(separator list-of-strings)‘](#join-separator-list-of-strings)
- [concat ‘(&rest strings)‘](#concat-rest-strings)
- [ensure ‘(s &key wrapped-in prefix suffix)‘ NEW in March, 2023](#ensure-s-key-wrapped-in-prefix-suffix-new-in-march-2023)
- [ensure-prefix, ensure-suffix ‘(start/end s)‘ NEW in March, 2023](#ensure-prefix-ensure-suffix-startend-s-new-in-march-2023)
- [ensure-wrapped-in ‘(start/end s)‘](#ensure-wrapped-in-startend-s)
- [insert ‘(string/char index s)‘](#insert-stringchar-index-s)
- [repeat ‘(count s)‘](#repeat-count-s)
- [add-prefix, add-suffix ‘(items s)‘](#add-prefix-add-suffix-items-s)
- [pad ‘(len s &key (pad-side :right) (pad-char #\Space))‘, pad-left, pad-right, pad-center (new in 0.16, 2019/12)](#pad-len-s-key-pad-side-right-pad-char-space-pad-left-pad-right-pad-center-new-in-016-201912) - [To shorter strings](#to-shorter-strings)
- [substring ‘(start end s)‘](#substring-start-end-s)
- [s-first ‘(s)‘](#s-first-s)
- [s-last ‘(s)‘](#s-last-s)
- [s-rest ‘(s)‘](#s-rest-s)
- [s-nth ‘(n s)‘](#s-nth-n-s)
- [shorten ‘(len s &key ellipsis)‘](#shorten-len-s-key-ellipsis)
- [To a fixed length](#to-a-fixed-length)
- [fit ‘(len s)‘](#fit-len-s)
- [To and from lists](#to-and-from-lists)
- [words ‘(s)‘](#words-s)
- [unwords ‘(strings)‘](#unwords-strings)
- [lines ‘(s &key omit-nulls)‘](#lines-s-key-omit-nulls)
- [unlines ‘(strings)‘](#unlines-strings)
- [split ‘(separator s &key omit-nulls limit start end regex)‘](#split-separator-s-key-omit-nulls-limit-start-end-regex)
- [rsplit ‘(separator s &key limit regex)‘](#rsplit-separator-s-key-limit-regex)
- [split-omit-nulls ‘(separator s &key regex)‘](#split-omit-nulls-separator-s-key-regex)
- [To and from files](#to-and-from-files)
- [from-file ‘(filename)‘](#from-file-filename)
- [to-file ‘(filename s)‘](#to-file-filename-s)
- [Predicates](#predicates)
- [emptyp ‘(s)‘](#emptyp-s)
- [blankp ‘(s)‘](#blankp-s)
- [starts-with-p ‘(start s &key ignore-case)‘](#starts-with-p-start-s-key-ignore-case)
- [ends-with-p ‘(end s &key ignore-case)‘](#ends-with-p-end-s-key-ignore-case)
- [containsp ‘(substring s &key (ignore-case nil))‘](#containsp-substring-s-key-ignore-case-nil)
- [s-member ‘(list s &key (ignore-case *ignore-case*) (test #’string=))‘](#s-member-list-s-key-ignore-case-ignore-case-test-string)
- [prefixp and suffixp ‘(items s)‘](#prefixp-and-suffixp-items-s)
- [wrapped-in-p (‘start/end‘ ‘s‘) NEW in March, 2023](#wrapped-in-p-startend-s-new-in-march-2023)
- [Case](#case)
- [Functions to change case: camel-case, snake-case,...](#functions-to-change-case-camel-case-snake-case)
- [downcase, upcase, capitalize ‘(s)‘ fixing a built-in suprise.](#downcase-upcase-capitalize-s-fixing-a-built-in-suprise)
- [downcasep, upcasep ‘(s)‘](#downcasep-upcasep-s)
- [alphap, lettersp ‘(s)‘](#alphap-lettersp-s)
- [alphanump, lettersnump ‘(s)‘](#alphanump-lettersnump-s)
- [ascii-p ‘(char/s)‘](#ascii-p-chars)
- [digitp ‘(s)‘](#digitp-s)
- [has-alpha-p, has-letters-p, has-alphanum-p ‘(s)‘](#has-alpha-p-has-letters-p-has-alphanum-p-s)
- [Others](#others)
- [replace-first ‘(old new s &key regex)‘](#replace-first-old-new-s-key-regex)
- [replace-all ‘(old new s &key regex)‘](#replace-all-old-new-s-key-regex)
- [replace-using ‘(replacement-list s &key regex)‘](#replace-using-replacement-list-s-key-regex)
- [remove-punctuation (s &key replacement)](#remove-punctuation-s-key-replacement)
- [prefix ‘(list-of-strings)‘ (renamed in 0.9)](#prefix-list-of-strings-renamed-in-09)
- [suffix ‘(list-of-strings)‘](#suffix-list-of-strings)
- [count-substring ‘(substring s &key start end)‘](#count-substring-substring-s-key-start-end)
- [s-assoc-value ‘(alist key)‘](#s-assoc-value-alist-key)
- [Macros](#macros)
- [string-case](#string-case)
- [match (experimental) · new in Feb, 2024](#match-experimental–new-in-feb-2024)
- [Changelog](#changelog)
- [Dev and test](#dev-and-test)
- [Main test suite](#main-test-suite)
- [Specific test suite](#specific-test-suite)
- [Specific test](#specific-test)
- [Test when defined](#test-when-defined)
- [See also](#see-also)

<!– markdown-toc end –>

## Install

Install with [Quicklisp](https://www.quicklisp.org/beta/):

(ql:quickload :str)

Add it in your .asd’s project dependencies, and call functions with the ‘str‘ prefix. It is not recommended to ‘:use :str‘ in a package. It’s safer to use the ‘str‘ prefix.

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")

Don’t have a full Common Lisp development environment yet ? Get
[Portacle](https://shinmera.github.io/portacle/), a portable and
multiplatform development environment shipping Emacs, Quicklisp, SBCL
and Git. See also [editor
support](https://lispcookbook.github.io/cl-cookbook/editor-support.html)
(Vim, Lem, Atom, Eclipse,…).

## Global parameters

Some parameters are common to various functions and often used:
‘:ignore-case‘ and ‘:omit-nulls‘.

Consequently we can also manage them with global parameters:

~~~lisp
(let ((str:*ignore-case* t))
(str:ends-with-p "BAR" "foobar"))
~~~

is equivalent to

~~~lisp
(str:ends-with-p "BAR" "foobar" :ignore-case t)
~~~

## Functions

### Tweak whitespace

#### trim ‘(s &key (char-bag *whitespaces*))‘

Removes all characters in ‘char-bag‘ (default: whitespaces) at the beginning and end of ‘s‘.
If supplied, ‘char-bag‘ has to be a sequence (e.g. string or list of characters).

“‘lisp
(str:trim " rst ") ;; => "rst"
(str:trim "+-*foo-bar*-+" :char-bag "+-*") => "foo-bar"
(str:trim "afood" :char-bag (concat "a" "d")) => "foo""
(str:trim "cdoooh" :char-bag (str:concat "c" "d" "h")) => "ooo"
“‘

Also ‘trim-left‘ and ‘trim-right‘.

Uses the built-in
[string-trim](https://lispcookbook.github.io/cl-cookbook/strings.html#trimming-blanks-from-the-ends-of-a-string)
where whitespaces are ‘’(#\Space #\Newline #\Backspace #\Tab #\Linefeed #\Page #\Return #\Rubout)‘.

#### collapse-whitespaces ‘(s)‘

Ensure there is only one space character between words. Remove newlines.

~~~lisp
(str:collapse-whitespaces "foo bar

baz")
;; "foo bar baz"
;;T
~~~

### To longer strings

#### join ‘(separator list-of-strings)‘

Join strings in list ‘list-of-strings‘ with ‘separator‘ (either a string or a char) in between.

“‘lisp
(join " " ’("foo" "bar" "baz")) ;; => "foo bar baz"
(join #\Space ’("foo" "bar" "baz")) ;; => "foo bar baz"
“‘

#### concat ‘(&rest strings)‘

Join strings into one.

“‘lisp
(concat "f" "o" "o") ;; => "foo"
“‘

Simple call of the built-in [concatenate](https://lispcookbook.github.io/cl-cookbook/strings.html#concatenating-strings).

We actually also have ‘uiop:strcat‘.

#### ensure ‘(s &key wrapped-in prefix suffix)‘ NEW in March, 2023

The "ensure-" functions return a string that has the specified prefix or suffix, appended if necessary.

This ‘str:ensure‘ function looks for the following key parameters, in order:

- ‘:wrapped-in‘: if non nil, call ‘str:ensure-wrapped-in‘. This checks that ‘s‘ both starts and ends with the supplied string or character.
- ‘:prefix‘ and ‘:suffix‘: if both are supplied and non-nil, call ‘str:ensure-suffix‘ followed by ‘str:ensure-prefix‘.
- ‘:prefix‘: call ‘str:ensure-prefix‘
- ‘:suffix‘: call ‘str:ensure-suffix‘.

Example:

~~~lisp
(str:ensure "abc" :wrapped-in "/") ;; => "/abc/"
(str:ensure "/abc" :prefix "/") ;; => "/abc" => no change, still one "/"
(str:ensure "/abc" :suffix "/") ;; => "/abc/" => added a "/" suffix.
~~~

These functions accept strings and characters:

~~~lisp
(str:ensure "/abc" :prefix #\/)
~~~

warn: if both ‘:wrapped-in‘ and ‘:prefix‘ (and/or ‘:suffix‘) are supplied together, ‘:wrapped-in‘ takes precedence and ‘:prefix‘ (and/or ‘:suffix‘) is ignored.

#### ensure-prefix, ensure-suffix ‘(start/end s)‘ NEW in March, 2023

Ensure that ‘s‘ starts with ‘start/end‘ (or ends with ‘start/end‘, respectively).

Return a new string with its prefix (or suffix) added, if necessary.

Example:

~~~lisp
(str:ensure-prefix "/" "abc/") => "/abc/" (a prefix was added)
;; and
(str:ensure-prefix "/" "/abc/") => "/abc/" (does nothing)
~~~

#### ensure-wrapped-in ‘(start/end s)‘

Ensure that ‘s‘ both starts and ends with ‘start/end‘.

Return a new string with the necessary added bits, if required.

It simply calls ‘str:ensure-suffix‘ followed by ‘str:ensure-prefix‘.

See also ‘str:wrapped-in-p‘ and ‘uiop:string-enclosed-p prefix s suffix‘.

~~~lisp
(str:ensure-wrapped-in "/" "abc") ;; => "/abc/" (added both a prefix and a suffix)
(str:ensure-wrapped-in "/" "/abc/") ;; => "/abc/" (does nothing)
~~~

#### insert ‘(string/char index s)‘

Insert the given string (or character) at the index ‘index‘ into ‘s‘ and return a
new string.

If ‘index‘ is out of bounds, just return ‘s‘.

“‘lisp
(str:insert "l" 2 "helo") ; => "hello"

(str:insert "o" 99 "hell") : => "hell"
“‘

#### repeat ‘(count s)‘

Make a string of ‘s‘ repeated ‘count‘ times.

“‘lisp
(repeat 3 "foo") ;; => "foofoofoo"
“‘

#### add-prefix, add-suffix ‘(items s)‘

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

#### pad ‘(len s &key (pad-side :right) (pad-char #\Space))‘, pad-left, pad-right, pad-center (new in 0.16, 2019/12)

Fill ‘s‘ with characters until it is of the given length. By default,
add spaces on the right:

~~~lisp
(str:pad 10 "foo")
"foo "
~~~

* ‘pad-side‘: one of ‘:right‘ (the default), ‘:left‘ or ‘:center‘. See ‘*pad-side*‘.
* ‘pad-char‘: the padding character (or string of one character). Defaults to a space. See ‘*pad-char*‘.

~~~lisp
(str:pad 10 "foo" :pad-side :center :pad-char "+")
"+++foo++++"
~~~

If the given length is smaller than the length o ‘s‘, return ‘s‘.

Filling with spaces can easily be done with format:

~~~lisp
(format nil "~va" len s) ;; => "foo "
(format nil "~v@a" 10 "foo") ;; => " foo" (with @)
~~~

### 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:

“‘lisp
(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:

“‘lisp
(s-first "foobar") ;; => "f"
(s-first "") ;; => ""
“‘

#### s-last ‘(s)‘

Return the last letter of ‘s‘.

#### s-rest ‘(s)‘

Return the rest substring of ‘s‘.

Examples:

“‘lisp
(s-rest "foobar") ;; => "oobar"
(s-rest "") ;; => ""
“‘

#### s-nth ‘(n s)‘

Return the nth letter of ‘s‘.

Examples:

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

You could also use

~~~lisp
(elt "test" 1)
;; => #\e
(string (elt "test" 1))
;; => "e"
~~~

#### shorten ‘(len s &key ellipsis)‘

If ‘s‘ is longer than ‘len‘, truncate it and add an ellipsis at the
end (‘...‘ by default). ‘s‘ is cut down to ‘len‘ minus the length of
the ellipsis (3 by default).

Optionally, give an ‘:ellipsis‘ keyword argument. Also set it globally
with ‘*ellipsis*‘.

~~~lisp
(shorten 8 "hello world")
;; => "hello..."
(shorten 3 "hello world")
;; => "..."
(shorten 8 "hello world" :ellipsis "-")
;; => "hello w-"
(let ((*ellipsis* "-"))
(shorten 8 "hello world"))
;; => "hello w-"
~~~

### To a fixed length

#### fit ‘(len s)‘

Fit this string to the given length:

- if it’s too long, shorten it (showing the ‘ellipsis‘),
- if it’s too short, add paddding (to the side ‘pad-side‘, adding the
character ‘pad-char‘).

As such, it accepts the same key arguments as ‘str:shorten‘ and
‘str:pad‘: ‘ellipsis‘, ‘pad-side‘, ‘pad-char‘…

~~~lisp
CL-USER> (str:fit 10 "hello" :pad-char "+")
"hello+++++"

CL-USER> (str:fit 10 "hello world" :ellipsis "…")
"hello wor…"
~~~

If, like me, you want to print a list of data as a table, see:

- [cl-ansi-term](https://github.com/vindarel/cl-ansi-term/)

~~~lisp
CL-USER> (ql:quickload "cl-ansi-term")
CL-USER> (term:table ’(("name" "age" "email")
("me" 7 "some@blah")
("me" 7 "some@with-some-longer.email"))
:column-width ’(10 4 20))
+———+—+——————-+
|name |age|email |
+———+—+——————-+
|me |7 |some@blah |
+———+—+——————-+
|me |7 |some@with-some-l(…)|
+———+—+——————-+
~~~

- [cl-ascii-table](https://github.com/telephil/cl-ascii-table/)

~~~lisp
CL-USER> (ql:quickload "cl-ascii-table")
CL-USER> (let ((table (ascii-table:make-table ’("Id" "Name" "Amount") :header "Infos")))
(ascii-table:add-row table ’(1 "Bob" 150))
(ascii-table:add-row table ’(2 "Joe" 200))
(ascii-table:add-separator table)
(ascii-table:add-row table ’("" "Total" 350))
(ascii-table:display table))

.———————.
| Infos |
+—-+——-+——–+
| Id | Name | Amount |
+—-+——-+——–+
| 1 | Bob | 150 |
| 2 | Joe | 200 |
+—-+——-+——–+
| | Total | 350 |
+—-+——-+——–+
NIL
~~~

### 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 &key omit-nulls)‘

Split string by newline character and return list of lines.

A terminal newline character does *not* result in an extra empty string
(new in **v0.14**, october 2019).

#### unlines ‘(strings)‘

Join the list of strings with a newline character.

#### split ‘(separator s &key omit-nulls limit start end regex)‘

Split into subtrings. If
‘omit-nulls‘ is non-nil, zero-length substrings are omitted.

By default, metacharacters are treated as normal characters.
If ‘regex‘ is not ‘nil‘, then ‘separator‘ is treated as regular expression.

“‘lisp
(split "+" "foo++bar") ;; => ("foo" "" "bar")
(split #\+ "foo++bar") ;; => ("foo" "" "bar")
(split "+" "foo++bar" :omit-nulls t) ;; => ("foo" "bar")

(split "[,|;]" "foo,bar;baz") ;; => ("foo,bar;baz")
(split "[,|;]" "foo,bar;baz" :regex t) ;; => ("foo" "bar" "baz")
“‘

cl-ppcre has an inconsistency such that when the separator appears at
the end, it doesn’t return a trailing empty string. But we do **since
v0.14** (october, 2019).

#### rsplit ‘(separator s &key limit regex)‘

Similar to ‘split‘, but split from the end. In particular, this will
be different from ‘split‘ when a ‘:limit‘ is provided, but in more
obscure cases it can be different when there are multiple different
ways to split the string.

“‘lisp
(rsplit "/" "/var/log/mail.log" :limit 2) ;; => ("/var/log" "mail.log")
“‘

~~~lisp
(cl-ppcre:split " " "a b c ")
("a" "b" "c")

(str:split " " "a b c ")
("a" "b" "c" "")
~~~

#### split-omit-nulls ‘(separator s &key regex)‘

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

### To and from files

#### 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‘](https://github.com/fare/asdf/blob/master/uiop/stream.lisp#L445)
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

#### emptyp ‘(s)‘

True if ‘s‘ is nil or the empty string:

“‘lisp
(emptyp nil) ;; => T
(emptyp "") ;; => T
(emptyp " ") ;; => NIL
“‘

See also ‘str:non-empty-string-p‘, which adds a ‘stringp‘ check.

#### blankp ‘(s)‘

True if ‘s‘ is empty or only contains whitespaces.

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

See also ‘str:non-blank-string-p‘.

#### starts-with-p ‘(start s &key ignore-case)‘

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

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

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

#### ends-with-p ‘(end s &key ignore-case)‘

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

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

‘end‘ can be a string or a character.

#### 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).

#### s-member ‘(list s &key (ignore-case *ignore-case*) (test #’string=))‘

Return T if ‘s’ is a member of ‘list’. Do not ignore case by default.

NOTE: ‘s-member‘’s arguments’ order is the reverse of CL’s ‘member‘.

If ‘:ignore-case‘ or ‘*ignore-case*‘ are not nil, ignore case (using
‘string-equal‘ instead of ‘string=‘).

Unlike CL’s ‘member‘, ‘s-member‘ returns T or NIL, instead of the tail of LIST whose first element satisfies the test.

#### prefixp and suffixp ‘(items s)‘

Return ‘s‘ if all ‘items‘ start (or end) with it.

See also ‘uiop:string-prefix-p prefix s‘, which returns ‘t‘ if
‘prefix‘ is a prefix of ‘s‘,

and ‘uiop:string-enclosed-p prefix s suffix‘, which returns ‘t‘ if ‘s‘
begins with ‘prefix‘ and ends with ‘suffix‘.

#### wrapped-in-p (‘start/end‘ ‘s‘) NEW in March, 2023

Does ‘s‘ start and end with ‘start/end’?

If true, return ‘s‘. Otherwise, return nil.

Example:

~~~lisp
(str:wrapped-in-p "/" "/foo/" ;; => "/foo/"
(str:wrapped-in-p "/" "/foo" ;; => nil
~~~

See also: ‘UIOP:STRING-ENCLOSED-P (prefix s suffix)‘.

### Case

#### Functions to change case: camel-case, snake-case,...

We use
[cl-change-case](https://github.com/rudolfochrist/cl-change-case/) (go
thank him and star the repo!).
We adapt these functions to also accept symbols and characters (like the inbuilt casing functions).
Also the functions return ‘nil‘ when argument is ‘nil‘.

The available functions are:

“‘
:no-case (s &key replacement)
:camel-case (s &key merge-numbers)
:dot-case
:header-case
:param-case
:pascal-case
:path-case
:sentence-case
:snake-case
:swap-case
:title-case
:constant-case
“‘

More documentation and examples are there.

#### downcase, upcase, capitalize ‘(s)‘ fixing a built-in suprise.

The functions ‘str:downcase‘, ‘str:upcase‘ and ‘str:capitalize‘ return
a new string. They call the built-in ‘string-downcase‘,
‘string-upcase‘ and ‘string-capitalize‘ respectively, but they fix
something surprising. When the argument is ‘nil‘, the built-ins return
"nil" or "NIL" or "Nil", a *string*. Indeed, they work on anything:

(string-downcase nil) ;; => "nil" the string !
(str:downcase nil) ;; nil

(string-downcase :FOO) ;; => "foo"

#### downcasep, upcasep ‘(s)‘

These functions return ‘t‘ if the given string contains at least one
letter and all its letters are lowercase or uppercase, respectively.

“‘lisp
(is (downcasep " a+,. ") t "downcasep with one letter and punctuation is true.")
(is (downcasep " +,. ") nil "downcasep with only punctuation or spaces is false")
“‘

#### alphap, lettersp ‘(s)‘

‘alphap‘ returns t if ‘s‘ contains at least one character and all characters are
alpha (as in ‘"^[a-zA-Z]+$"‘).

‘lettersp‘ works for unicode letters too.

~~~lisp
(is (alphap "abcdeé") nil "alphap is nil with accents")
(is (lettersp "éß") t "lettersp is t with accents and ß")
~~~

#### alphanump, lettersnump ‘(s)‘

‘alphanump‘ returns t if ‘s‘ contains at least one character and all characters are alphanumeric (as in ‘^[a-zA-Z0-9]+$‘).

‘lettersnump‘ also works on unicode letters (as in ‘^[\\p{L}a-zA-Z0-9]+$‘).

#### ascii-p ‘(char/s)‘

Return t if the character / string is an ASCII character / is composed of ASCII characters.

An ASCII character has a ‘char-code‘ inferior to 128.

#### digitp ‘(s)‘

Returns t if ‘s‘ contains at least one character and all characters are numerical (as for ‘digit-char-p‘).

#### has-alpha-p, has-letters-p, has-alphanum-p ‘(s)‘

Return t if ‘s‘ has at least one alpha, letter, alphanum character (as with ‘alphanumericp‘).

### Others

#### replace-first ‘(old new s &key regex)‘

Replace the first occurence of ‘old‘ by ‘new‘ in ‘s‘.

By default, metacharacters are treated as normal characters.
If ‘regex‘ is not ‘nil‘, then ‘old‘ is treated as regular expression.

“‘lisp
(replace-first "a" "o" "faa") ;; => "foa"
(replace-first "fo+" "frob" "foofoo bar" :regex t) ;; => "frobfoo bar"
“‘

Uses
[cl-ppcre:regex-replace](http://weitz.de/cl-ppcre/#regex-replace)
but quotes the user input to not treat it as a regex (if regex is nil).

#### replace-all ‘(old new s &key regex)‘

Replace all occurences of ‘old‘ by ‘new‘ in ‘s‘.

By default, metacharacters are treated as normal characters.
If ‘regex‘ is not ‘nil‘, ‘old‘ is treated as regular expression.

“‘lisp
(replace-all "a" "o" "faa") ;; => "foo"
(replace-all "fo+" "frob" "foofoo bar" :regex t) ;; => "frobfrob bar"
“‘

Uses
[cl-ppcre:regex-replace-all](http://weitz.de/cl-ppcre/#regex-replace-all)
but quotes the user input to not treat it as a regex (if regex is nil).

If the replacement is only one character, you can use ‘substitute‘:

(substitute #\+ #\Space "foo bar baz")
;; "foo+bar+baz"

#### replace-using ‘(replacement-list s &key regex)‘

Replace all associations given by pairs in a replacement-list and return a new string.

The ‘replacement-list‘ alternates a string to replace (case sensitive) and its replacement.
By default, metacharacters in the string to replace are treated as normal characters.
If ‘regex‘ is not ‘nil‘, strings to replace are treated as regular expression.

Example:

“‘lisp
(replace-using (list "%phone%" "987")
"call %phone%")
;; => "call 987"

(replace-using (list "fo+" "frob"
"ba+" "Bob")
"foo bar"
:regex t)
;; => "frob Bobr"
“‘

#### remove-punctuation (s &key replacement)

Remove the punctuation characters from ‘s‘, replace them with
‘replacement‘ (defaults to a space) and strip continuous whitespace.

~~~lisp
(str:remove-punctuation "I say: - ’Hello, world?’") ;; => "I say Hello world"
~~~

Use ‘str:no-case‘ to remove punctuation and return the string as lower-case.

#### 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)‘

Find the common suffix between strings.

#### count-substring ‘(substring s &key start end)‘
Counts the non-overlapping occurrences of ‘substring‘ in ‘s‘.
You could also count only the ocurrencies between ‘start‘ and ‘end‘.

Examples:
~~~ lisp
(count-substring "abc" "abcxabcxabc")
;; => 3
~~~
~~~lisp
(count-substring "abc" "abcxabcxabc" :start 3 :end 7)
;; => 1
~~~

#### s-assoc-value ‘(alist key)‘

Returns the value of a cons cell in ‘alist‘ with key ‘key‘, when ‘key‘ is a string.
The second return value is the cons cell, if any was matched.

The arguments are in the opposite order of ‘cl:assoc‘’s, but are consistent
with ‘alexandria:assoc-value‘ (and ‘str‘).

“‘lisp
(s-assoc-value ’(("hello" . 1)) "hello")
;; 1
;; ("hello" . 1)

(alexandria:assoc-value ’(("hello" . 1)) "hello")
;; NIL
(alexandria:assoc-value ’(("hello" . 1)) "hello" :test #’string=)
;; 1
;; ("hello" . 1)

(assoc "hello" ’(("hello" . 1)))
;; NIL
(assoc "hello" ’(("hello" . 1)) :test #’string=)
;; ("hello" . 1)
(cdr *)
;; 1
“‘

## Macros

### string-case

A case-like macro that works with strings (CL case’s test function is
‘eql‘, and that isn’t enough for strings).

Example:

~~~lisp
(str:string-case "hello"
("foo" 1)
(("hello" "test") 5)
(nil (print "input is nil"))
(otherwise (print "non of the previous forms was caught.")))
~~~

You might also like pattern matching. The example below with
[trivia](https://github.com/guicho271828/trivia/) is very similar:

~~~lisp
(trivia:match "hey"
("hey" (print "it matched"))
(otherwise :nothing))
~~~

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

### match (experimental) · new in Feb, 2024

A COND-like macro to match substrings and bind variables to matches. Regular expressions are allowed for matches.

‘_‘ is a placeholder that is ignored.

THIS MACRO IS EXPERIMENTAL and might break in future releases.

Example:

“‘lisp
(str:match "a 1 b 2 d"
(("a " x " b " y " d") ;; => matched
(+ (parse-integer x) (parse-integer y)))
(t
’default-but-not-for-this-case)) ;; default branch
;; => 3

(str:match "a 1 b c d"
(("a 2 b" _ "d") ;; => not matched
(print "pass"))
(("a " _ " b c d") ;; => matched
"here we go")
(t ’default-but-not-for-this-case)) ;; default branch
;; => "here we go"
“‘

Match with regexs:

“‘lisp
(str:match "123 hello 456"
(("\\d+" s "\\d+")
s)
(t "nothing"))
;; => " hello "
“‘

## Changelog

* Feb, 2024:
* added the ‘match‘ macro. It is EXPERIMENTAL and might change in future versions. We welcome your bug reports and feedback.
* 0.21, November, 2023:
* added the ‘regex‘ key argument to ‘split‘, ‘rsplit‘, ‘split-omit-nulls‘.
* August, 2023:
* added the ‘regex‘ key argument to the ‘replace-*‘ functions.
* March, 2023:
* added ‘str:ensure‘, ‘str:ensure-prefix‘, ‘str:ensure-suffix‘, ‘str:ensure-wrapped-in‘ and ‘str:wrapped-in-p‘.
* January, 2023: added the ‘:char-barg‘ parameter to ‘trim‘, ‘trim-left‘, ‘trim-right‘.
- minor: ‘ends-with-p‘ now works with a character.
* June, 2022: small breaking change: fixed ‘prefixp‘ when used with a smaller prefix: "f" was not recognized as a prefix of "foobar" and "foobuz", only "foo" was. Now it is fixed. Same for ‘suffixp‘.
* Feb, 2022: added ‘fit‘: fit the string to the given length: either shorten it, either padd padding.
* 0.20, May, 2021: added ‘ascii-p‘.
* 0.19.1, May, 2021: speed up ‘join‘ (by a factor of 4).
* 0.19, October, 2020: added s-member
*0.18.1, September, 2020: fix replace-all edge case when the replacement string ends with two backslashes and a single quote.
* 0.18, June, 2020: added ‘replace-using‘.
* 0.17, April 2020:
- added ‘collapse-whitespaces‘
- ‘join‘ and ‘split‘ also accept a char as separator
- fixed ‘remove-punctuation‘ that did not respect the case. Use ‘no-case‘ for this
- fixed ‘from-file‘ "odd number of arguments" error.
* 0.16, November 2019: added ‘pad‘, ‘pad-[left, right, center]‘.
* 0.15, October 2019: added functions to change case (based on cl-change-case).
added remove-punctuation.
* 0.14, October, 2019: fixed the cl-ppcre inconsistency in ‘split‘ and ‘lines‘. A trailing separator now returns a trailing empty string.

Before:

~~~lisp
(str:split " " "a b c ")
("a" "b" "c") ;; like cl-ppcre:split
~~~

Now:

~~~lisp
(str:split " " "a b c ")
("a" "b" "c" "")
~~~

* august, 2019: deprecated ‘prune‘, renamed to ‘shorten‘.
* added ‘:limit‘ to ‘split‘.
* 0.13 june, 2019
- added ‘insert‘
* 0.12
- added case predicates (‘downcasep‘, ‘alphap‘, ‘has-x‘ and friends).
* 0.11 (Quicklisp end of march, 2019, also in Ultralisp)
- added ‘str:downcase‘, ‘str:upcase‘ and ‘str:capitalize‘, that fix the ‘nil‘ argument surprise.
* 0.10
- ‘split‘ doesn’t fix cl-ppcre’s inconsistency anymore (when the separator appears at the end). See issue #18. So ‘(str:split "xx" "fooxxbarxx")‘ doesn’t return a trailing ‘""‘.
- added ‘s-last‘
- ‘s-first‘ and friends return ‘nil‘ when appropriate, not ‘""‘.
* 0.9
- added ‘s-first‘ , ‘s-rest‘ and ‘s-nth‘
- added ‘prefix‘ and ‘suffix‘ functions and predicates.
- added ‘prune‘.
* 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

Regression testing is implemented with [fiveam](https://github.com/lispci/fiveam).

### Main test suite

Either use
“‘lisp
(asdf:test-system :str)
“‘

or load the test package ‘str.test‘ and then
“‘lisp
(fiveam:run! ’test-str:str)
“‘

### Specific test suite

“‘lisp
(fiveam:run! ’test-str:replace-functions)
“‘

Test suite names:
- replace-functions
- lengthen-functions
- ensure-functions
- pad-functions
- substring-functions
- list-functions
- from-list-to-string
- from-list-to-list
- from-string-to-list
- predicates, case-functions
- miscellaneous

### Specific test

“‘lisp
(fiveam:run! ’test-str::downcase) ;; (test symbols are unexported)
“‘

### Test when defined

First you need to
“‘lisp
(setf fiveam:*run-test-when-defined* t)
“‘
then the test is run after each definition / compilation.
This can be done with C-c C-c on emacs.

## See also

* the [Common Lisp Cookbook](https://lispcookbook.github.io/cl-cookbook/strings.html), strings page.
* my [Common Lisp course on Udemy: from novice to effective developer](https://www.udemy.com/course/common-lisp-programming/?referralCode=2F3D698BBC4326F94358). Check out my blog for regular coupons.
* https://lisp-journey.gitlab.io/
* video: [how to create a Common Lisp project from scratch with our project generator](https://www.youtube.com/watch?v=XFc513MJjos): it sums up in 5 minutes what took me a much longer time to gather.

Inspired by the famous Emacs Lisp’s [s.el](https://github.com/magnars/s.el).

Version

0.21

Dependencies
  • cl-ppcre (system).
  • cl-ppcre-unicode (system).
  • cl-change-case (system).
Source

str.asd.

Child Components

3 Files

Files are sorted by type and then listed depth-first from the systems components trees.


3.1 Lisp


3.1.1 str/str.asd

Source

str.asd.

Parent Component

str (system).

ASDF Systems

str.


3.1.2 str/str.lisp

Source

str.asd.

Parent Component

str (system).

Packages

str.

Public Interface
Internals

3.2 Static


3.2.1 str/README.md

Source

str.asd.

Parent Component

str (system).


4 Packages

Packages are listed by definition order.


4.1 str

Source

str.lisp.

Use List

common-lisp.

Public Interface
Internals

5 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


5.1 Public Interface


5.1.1 Special variables

Special Variable: *ellipsis*

Ellipsis to add to the end of a truncated string (see ‘shorten’).

Package

str.

Source

str.lisp.

Special Variable: *ignore-case*
Package

str.

Source

str.lisp.

Special Variable: *omit-nulls*
Package

str.

Source

str.lisp.

Special Variable: *pad-char*

Padding character to use with ‘pad’. It can be a string of one character.

Package

str.

Source

str.lisp.

Special Variable: *pad-side*

The side of the string to add padding characters to. Can be one of :right, :left and :center.

Package

str.

Source

str.lisp.

Special Variable: *whitespaces*

On some implementations, linefeed and newline represent the same character (code).

Package

str.

Source

str.lisp.

Special Variable: +version+
Package

str.

Source

str.lisp.


5.1.2 Macros

Macro: match (str &body match-branches)

A COND-like macro to match substrings and bind variables to matches. Regular expressions are allowed for matches.

_ is a placeholder that is ignored.

THIS MACRO IS EXPERIMENTAL and might break in future releases.

Example:

(str:match "a 1 b 2 d"
(("a " x " b " y " d") ;; => matched
(+ (parse-integer x) (parse-integer y)))
(t
’default-but-not-for-this-case)) ;; default branch
;; => 3

(str:match "a 1 b c d"
(("a 2 b" _ "d") ;; => not matched
(print "pass"))
(("a " _ " b c d") ;; => matched
"here we go")
(t ’default-but-not-for-this-case)) ;; default branch
;; => "here we go"

Match with regexs:

(str:match "123 hello 456"
(("\d+" s "\d+")
s)
(t "nothing"))
;; => " hello "

Package

str.

Source

str.lisp.

Macro: string-case (str &body forms)

A case-like macro that works with strings (case works only with symbols).
You can either supply single-item clauses, multiple-items clauses, or otherwise.

Example:

(str:string-case input
("foo" (do something))
(("hello" "test") 5)
(nil (print "input is nil")
(otherwise (print "none of the previous forms was caught")))

You might also like pattern matching with ‘str:match’.

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

Package

str.

Source

str.lisp.


5.1.3 Ordinary functions

Function: add-prefix (items s)

Prepend s to the front of each item.

Package

str.

Source

str.lisp.

Function: add-suffix (items s)

Append s to the end of each item.

Package

str.

Source

str.lisp.

Function: alpha? (s)

Return t if ‘s’ contains at least one character and all characters are alpha (in [a-zA-Z]). See also ‘lettersp’, which checks for unicode letters.

Package

str.

Alias for

alphap.

Function: alphanum? (s)

Return t if ‘s’ contains at least one character and all characters are alphanumeric. See also ‘lettersnump’ which also works on unicode letters.

Package

str.

Alias for

alphanump.

Function: alphanump (s)

Return t if ‘s’ contains at least one character and all characters are alphanumeric. See also ‘lettersnump’ which also works on unicode letters.

Package

str.

Source

str.lisp.

Function: alphap (s)

Return t if ‘s’ contains at least one character and all characters are alpha (in [a-zA-Z]). See also ‘lettersp’, which checks for unicode letters.

Package

str.

Source

str.lisp.

Function: ascii-char-p (char)

Return t if ‘char’ is an ASCII char (its char code is below 128).

Package

str.

Source

str.lisp.

Function: ascii-p (char/s)

If ‘char/s’ is a character, return t if it is an ASCII character (its char code is below 128). If ‘char/s’ is a string, return t if every character is ASCII.

Package

str.

Source

str.lisp.

Function: blank? (s)

Is s nil or only contains whitespaces ?

Package

str.

Alias for

blankp.

Function: blankp (s)

Is s nil or only contains whitespaces ?

Package

str.

Source

str.lisp.

Function: camel-case (s &key merge-numbers)

Transform ‘s’ to camelCase.
Dot-separated numbers like 1.2.3 will be replaced by underscores 1_2_3 unless MERGE-NUMBERS is non-nil.

Examples:
(camel-case "Foo fooF") => "fooFooF"
(camel-case (quote foo{foo.f)) => "fooFooF"
(camel-case #F) => "f"
(camel-case nil) => nil

Package

str.

Source

str.lisp.

Function: capitalize (s)

Return the capitalized version of ‘s’.
Calls the built-in ‘string-capitalize’, but returns nil if ‘s’ is nil (instead of the string "Nil").

Examples:
(capitalize "Foo fooF") => "Foo fooF"
(capitalize :foo{foo.f) => "Foo{Foo.F"
(capitalize #f) => "F"
(capitalize nil) => nil

Package

str.

Source

str.lisp.

Function: collapse-whitespaces (s)

Ensure there is only one space character between words. Remove newlines.

Package

str.

Source

str.lisp.

Function: common-prefix (items)

Find the common prefix between strings.

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

Example: ‘(str:prefix ’("foobar" "foozz"))‘ => "foo"

- items: list of strings
- Return: a string.

Package

str.

Alias for

prefix.

Function: concat (&rest strings)

Join all the string arguments into one string.

Package

str.

Source

str.lisp.

Function: constant-case (s)

Transform ‘s’ to CONSTANT_CASE.

(constant-case "Foo fooF") => "FOO_FOO_F" (constant-case :foo{foo.f) => "FOO_FOO_F" (constant-case #f) => "F" (constant-case nil) => nil

Package

str.

Source

str.lisp.

Function: contains? (substring s &key ignore-case)

Return ‘t‘ if ‘s‘ contains ‘substring‘, nil otherwise. Ignore the case with ‘:ignore-case t‘. A simple call to the built-in ‘search‘ (which returns the position of the substring).

Package

str.

Alias for

containsp.

Function: containsp (substring s &key ignore-case)

Return ‘t‘ if ‘s‘ contains ‘substring‘, nil otherwise. Ignore the case with ‘:ignore-case t‘. A simple call to the built-in ‘search‘ (which returns the position of the substring).

Package

str.

Source

str.lisp.

Function: count-substring (substring s &key start end ignore-case)

Return the non-overlapping occurrences of ‘substring’ in ‘s’.
You could also count only the ocurrencies between ‘start’ and ‘end’. When ‘ignore-case‘ is T, ignore case when counting matches.

Examples:
(count-substring "abc" "abcxabcxabc")
;; => 3

(count-substring "abc" "abcxabcxabc" :start 3 :end 7)
;; => 1

Package

str.

Source

str.lisp.

Function: digit? (s)

Return t if ‘s’ contains at least one character and all characters are numerical.

Package

str.

Alias for

digitp.

Function: digitp (s)

Return t if ‘s’ contains at least one character and all characters are numerical.

Package

str.

Source

str.lisp.

Function: dot-case (s)

Transform ‘s’ to dot.case.

Examples:
(dot-case "Foo fooF") => "foo.foo.f" (dot-case :foo{foo-f) => "foo.foo.f" (dot-case #F) => "f"
(dot-case nil) => nil

Package

str.

Source

str.lisp.

Function: downcase (s)

Return the lowercase version of ‘s’.
Calls the built-in ‘string-downcase’, but returns nil if ‘s’ is nil (instead of the string "nil").

Examples:
(downcase "Foo fooF") => "foo foof"
(downcase :foo{foo.f) => "foo{foo.f"
(downcase #F) => "f"
(downcase nil) => nil

Package

str.

Source

str.lisp.

Function: downcase? (s)

Return t if all alphabetical characters of ‘s’ are lowercase, and ‘s’ contains at least one letter.

Package

str.

Alias for

downcasep.

Function: downcasep (s)

Return t if all alphabetical characters of ‘s’ are lowercase, and ‘s’ contains at least one letter.

Package

str.

Source

str.lisp.

Function: empty? (s)

Is s nil or the empty string ?

Package

str.

Alias for

emptyp.

Function: emptyp (s)

Is s nil or the empty string ?

Package

str.

Source

str.lisp.

Function: ends-with-p (end s &key ignore-case)

Return t if s ends with the substring ’end’, nil otherwise.

END can be a character or a string.

Package

str.

Source

str.lisp.

Function: ends-with? (end s &key ignore-case)

Return t if s ends with the substring ’end’, nil otherwise.

END can be a character or a string.

Package

str.

Alias for

ends-with-p.

Function: ensure (s &key wrapped-in prefix suffix)

The ensure functions return a string that has the specified prefix or suffix, appended if necessary.

This function looks for the following parameters, in order:

- :wrapped-in : if non nil and non empty, call STR:ENSURE-WRAPPED-IN.
- :prefix and :suffix : if both are supplied and non-nil, call STR:ENSURE-SUFFIX followed by STR:ENSURE-PREFIX.
- :prefix : call STR:ENSURE-PREFIX
- :suffix : call STR:ENSURE-SUFFIX.

warn: if both :wrapped-in and :prefix (and/or :suffix) are supplied together, :wrapped-in takes precedence and :prefix (and/or :suffix) is ignored.

Example:

(str:ensure "abc" :wrapped-in "/") ;; => "/abc/"
(str:ensure "/abc" :prefix "/") ;; => "/abc" (no change, still one "/")
(str:ensure "/abc" :suffix "/") ;; => "/abc/" (added a "/" suffix)

These fonctions accept strings and characters:

(str:ensure "/abc" :prefix #\/)

Package

str.

Source

str.lisp.

Function: ensure-prefix (start s)

Ensure that ‘s’ starts with ‘start’.
Return a new string with its prefix added, if necessary.

Example:

(str:ensure-prefix "/" "abc/") ;; => "/abc/" (str:ensure-prefix "/" "/abc/") ;; => "/abc/" (does nothing)

See also ‘str:ensure-suffix’ and ‘str:ensure-wrapped-in’.

Package

str.

Source

str.lisp.

Function: ensure-suffix (end s)

Ensure that ‘s’ ends with ‘end’.
Return a new string with its suffix added, if necessary.

Example:

(str:ensure-suffix "/" "/abc") ;; => "/abc/" (str:ensure-suffix "/" "/abc/") ;; => "/abc/" (does nothing)

See also ‘str:ensure-prefix’ and ‘str:ensure-wrapped-in’.

Package

str.

Source

str.lisp.

Function: ensure-wrapped-in (start/end s)

Ensure that S starts and ends with ‘START/END’.
Return a new string.

Example:

(str:ensure-wrapped-in "/" "abc") ;; => "/abc/" (str:ensure-wrapped-in "/" "/abc/") ;; => "/abc/" (does nothing)

See also: ‘str:enclosed-by-p’.

Package

str.

Source

str.lisp.

Function: fit (len s &key pad-char pad-side ellipsis)

Fit this string to the given length:
- if it’s too long, shorten it (showing the ‘ellipsis’),
- if it’s too short, add paddding (to the side ‘pad-side’, adding the character ‘pad-char’).

Package

str.

Source

str.lisp.

Function: from-file (pathname &rest keys)

Read the file and return its content as a string.

It simply uses uiop:read-file-string. There is also uiop:read-file-lines.

Example: (str:from-file "path/to/file.txt" :external-format :utf-8)

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

Package

str.

Source

str.lisp.

Function: has-alpha-p (s)

Return t if ‘s’ has at least one alpha character ([a-zA-Z]).

Package

str.

Source

str.lisp.

Function: has-alphanum-p (s)

Return t if ‘s’ has at least one alphanumeric character.

Package

str.

Source

str.lisp.

Function: has-letters-p (s)

Return t if ‘s’ contains at least one letter (considering unicode, not only alpha characters).

Package

str.

Source

str.lisp.

Function: header-case (s)

Transform ‘s’ to Header-Case.

Examples:
(header-case "Foo fooF") => "Foo-Foo-F" (header-case ’foo{foo.f) => "Foo-Foo-F" (header-case #f) => "F" (header-case nil) => nil

Package

str.

Source

str.lisp.

Function: insert (string/char index s)

Insert the given string (or character) at the ‘index’ into ‘s’ and return a new string.

If ‘index’ is out of bounds, ignore and return ‘s’.

Package

str.

Source

str.lisp.

Function: join (separator strings)

Join all the strings of the list with a separator.

‘separator’ can be a string or a character.

Example:
(str:join "," ’("a" "b" "c")
=> "a,b,c"

Package

str.

Source

str.lisp.

Function: letters? (s)

Return t if ‘s’ contains only letters (including unicode letters).

(alphap "éß") ;; => nil
(lettersp "éß") ;; => t

Package

str.

Alias for

lettersp.

Function: lettersnump (s)

Return t if ‘s’ contains only letters (including unicode letters) and digits.

Package

str.

Source

str.lisp.

Function: lettersp (s)

Return t if ‘s’ contains only letters (including unicode letters).

(alphap "éß") ;; => nil
(lettersp "éß") ;; => t

Package

str.

Source

str.lisp.

Function: lines (s &key omit-nulls)

Split the string by newline characters and return a list of lines. A terminal newline character does NOT result in an extra empty string.

Package

str.

Source

str.lisp.

Function: no-case (s &key replacement)

Transform ‘s’ to lower case space delimited. Use REPLACEMENT as delimiter.

Examples:
(no-case "Foo fooF" :replacement ",") => "foo,foo,f"
(no-case ’foo{foo.f) => "foo foo f"
(no-case #F) => "f"
(no-case nil) => nil

Package

str.

Source

str.lisp.

Function: non-blank-string-p (s)

Return t if ‘s’ is a string and is non blank (it doesn’t exclusively contain whitespace characters).

Like ‘(not (blankp s))’, with a ‘stringp’ check. Useful in context.

Package

str.

Source

str.lisp.

Function: non-empty-string-p (s)

Return t if ‘s’ is a string and is non-empty.

Like ‘(not (emptyp s))’, with a ‘stringp’ check. Useful in context.

Package

str.

Source

str.lisp.

Function: numeric? (s)

Return t if ‘s’ contains at least one character and all characters are numerical.

Package

str.

Alias for

digitp.

Function: numericp (s)

Return t if ‘s’ contains at least one character and all characters are numerical.

Package

str.

Alias for

digitp.

Function: pad (len s &key pad-side pad-char)

Fill ‘s’ with characters until it is of the given length. By default, add spaces on the right.

Filling with spaces can be done with format:

(format nil "~v@a" len s) ;; with or without the @ directive

‘pad-side’: to pad ‘:right’ (the default), ‘:left’ or ‘:center’.
‘pad-char’: padding character (or string of one character). Defaults to a space.

Package

str.

Source

str.lisp.

Function: pad-center (len s &key pad-char)
Package

str.

Source

str.lisp.

Function: pad-left (len s &key pad-char)
Package

str.

Source

str.lisp.

Function: pad-right (len s &key pad-char)
Package

str.

Source

str.lisp.

Function: param-case (s)

Transform ‘s’ to param-case.

Examples:
(param-case "Foo fooF") => "foo-foo-f" (param-case (quote foo{foo.f)) => "foo-foo-f" (param-case #F) => "f"
(param-case nil) => nil

Package

str.

Source

str.lisp.

Function: pascal-case (s)

Transform ‘s’ to Pascal Case

Examples:
(pascal-case "Foo fooF") => "FooFooF" (pascal-case :foo{foo.f) => "FooFooF" (pascal-case #f) => "F" (pascal-case nil) => nil

Package

str.

Source

str.lisp.

Function: path-case (s)

Transform ‘s’ to path/case

Examples:
(path-case "Foo fooF") => "foo/foo/f" (path-case :foo{foo.f) => "foo/foo/f" (path-case #F) => "f"
(path-case nil) => nil

Package

str.

Source

str.lisp.

Function: prefix (items)

Find the common prefix between strings.

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

Example: ‘(str:prefix ’("foobar" "foozz"))‘ => "foo"

- items: list of strings
- Return: a string.

Package

str.

Source

str.lisp.

Function: prefix? (items prefix)

Return PREFIX if all ITEMS start with it.

Package

str.

Alias for

prefixp.

Function: prefixp (items prefix)

Return PREFIX if all ITEMS start with it.

Package

str.

Source

str.lisp.

Function: prune (len s &key ellipsis)

If s is longer than ‘len’, truncate it to this length and add the ‘*ellipsis*’ at the end ("..." by default). Cut it down to ‘len’ minus the length of the ellipsis.

Package

str.

Alias for

shorten.

Function: remove-punctuation (s &key replacement)

Remove the punctuation characters from ‘s’, replace them with ‘replacement’ (defaults to a space) and strip continuous whitespace.

Package

str.

Source

str.lisp.

Function: repeat (count s)

Make a string of S repeated COUNT times.

Package

str.

Source

str.lisp.

Function: replace-all (old new s &key regex)

Replace all occurences of ‘old’ by ‘new’ in ‘s’.

By default, metacharacters are treated as normal characters.
If ‘regex’ is not nil, ‘old’ is treated as a regular expression.

Examples:
(replace-all "+" "’\’" "foo+bar") ;; => "foo’\’bar"
(replace-all "fo+" "frob" "foofoo bar" :regex t) ;; => "frobfrob bar"

Package

str.

Source

str.lisp.

Function: replace-first (old new s &key regex)

Replace the first occurence of ‘old‘ by ‘new‘ in ‘s‘.

By default, metacharacters are treated as normal characters.
If ‘regex’ is not nil, ‘old’ is treated as a regular expression.

Examples:
(replace-first "aa" "oo" "faaaa") => "fooaa"
(replace-first "fo+" "frob" "foofoo bar" :regex t) => "frobfoo bar"

Package

str.

Source

str.lisp.

Function: replace-using (replacement-list s &key regex)

Replace all associations given by pairs in a list and return a new string.

The ‘replacement-list’ alternates a string to replace (case sensitive) and its replacement. By default, metacharacters in the string to replace are treated as normal characters. If ‘regex’ is not nil, strings to replace are treated as regular expressions.

Example:
(replace-using (list "{{phone}}" "987")
"call {{phone}}")
=> "call 987"

(replace-using (list "fo+" "frob"
"ba+" "Bob")
"foo bar"
:regex t)
=> "frob Bobr"

It calls ‘replace-all’ as many times as there are replacements to do.

Package

str.

Source

str.lisp.

Function: rsplit (sep s &key omit-nulls limit regex)

Similar to ‘split’, except we split from the end. In particular,
the results will be be different when ‘limit‘ is provided.

If ‘regex’ is not ‘nil‘, ‘separator’ is treated as a regular expression.

Package

str.

Source

str.lisp.

Function: s-assoc-value (alist key)

Return the value of a cons cell in ‘alist’ with key ‘key’, tested with ‘string-equal’ (case-insensitive).
The second return value is the cons cell.

Package

str.

Source

str.lisp.

Function: s-first (s)

Return the first substring of ‘s’.

Package

str.

Source

str.lisp.

Function: s-last (s)

Return the last substring of ‘s’.

Package

str.

Source

str.lisp.

Function: s-member (list s &key test ignore-case)

Return T if ‘s’ is a member of ‘list’. Do not ignore case by default.

NOTE: S-MEMBER’s arguments’ order is the reverse of CL:MEMBER.

If ‘:ignore-case’ or ‘*ignore-case*’ are not nil, ignore case (using ‘string-equal’ instead of ‘string=’).

Unlike CL:MEMBER, S-MEMBER returns T or NIL, instead of the tail of LIST whose first element satisfies the test.

Package

str.

Source

str.lisp.

Function: s-nth (n s)

Return the nth substring of ‘s’.

You could also use (string (elt "test" 1)) ;; => "e"

Package

str.

Source

str.lisp.

Function: s-rest (s)

Return the rest substring of ‘s’.

Package

str.

Source

str.lisp.

Function: sentence-case (s)

Transform ‘s’ to Sentence case

Examples:
(sentence-case "Foo.fooF") => "Foo foo f" (sentence-case (quote foo{foo.f)) => "Foo foo f" (sentence-case #f) => "F"
(sentence-case nil) => nil

Package

str.

Source

str.lisp.

Function: shorten (len s &key ellipsis)

If s is longer than ‘len’, truncate it to this length and add the ‘*ellipsis*’ at the end ("..." by default). Cut it down to ‘len’ minus the length of the ellipsis.

Package

str.

Source

str.lisp.

Function: snake-case (s)

Transform ‘s’ to snake_case

Examples:
(snake-case "Foo fooF") => "foo_foo_f" (snake-case ’foo{foo.f) => "foo_foo_f" (snake-case #f) => "f"
(snake-case nil) => nil

Package

str.

Source

str.lisp.

Function: split (separator s &key omit-nulls limit start end regex)

Split s into substring by separator (cl-ppcre takes a regex, we do not).

‘limit’ limits the number of elements returned (i.e. the string is split at most ‘limit’ - 1 times).
If ‘regex’ is not nil, ‘separator’ is treated as a regular expression.

Examples:
(str:split "," "foo,bar") ;; => ("foo" "bar")
(str:split "[,|;]" "foo,bar;baz" :regex t) ;; => ("foo" "bar" "baz")

Package

str.

Source

str.lisp.

Function: split-omit-nulls (separator s &key regex)

Call ‘split’ with :omit-nulls to t.

Can be clearer in certain situations.

If ‘regex’ is not nil, ‘separator’ is treated as a regular expression.

Package

str.

Source

str.lisp.

Function: starts-with-p (start s &key ignore-case)

Return t if S starts with the substring ‘START’, nil otherwise.

START can be a string or a character.

Package

str.

Source

str.lisp.

Function: starts-with? (start s &key ignore-case)

Return t if S starts with the substring ‘START’, nil otherwise.

START can be a string or a character.

Package

str.

Alias for

starts-with-p.

Function: 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.

Package

str.

Source

str.lisp.

Function: suffix (items)

Find the common suffix between strings.

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

Example: ‘(str:suffix ’("foobar" "zzbar"))‘ => "bar"

- items: list of strings
- Return: a string.

Package

str.

Source

str.lisp.

Function: suffix? (items suffix)

Return ‘suffix’ if all items end with it. Otherwise, return nil

Package

str.

Alias for

suffixp.

Function: suffixp (items suffix)

Return ‘suffix’ if all items end with it. Otherwise, return nil

Package

str.

Source

str.lisp.

Function: swap-case (s)

Reverse case for each character in ‘s’.

Examples:
(swap-case "Foo fooF") => "fOO FOOf" (swap-case :FOO{FOO.F) => "foo{foo.f" (swap-case #f) => "F"
(swap-case nil) => nil

Package

str.

Source

str.lisp.

Function: title-case (s)

Transform ‘s’ to Title Case

Examples:
(title-case "Foo fooF") => "Foo Foo F" (title-case :foo{foo.f) => "Foo Foo F" (title-case #f) => "F"
(title-case nil) => nil

Package

str.

Source

str.lisp.

Function: to-file (pathname s &key if-exists if-does-not-exist)

Write string ‘s’ to file ‘pathname’. If the file does not exist, create it (use ‘:if-does-not-exist’), if it already exists, replace its content (‘:if-exists’).

Returns the string written to file.

Package

str.

Source

str.lisp.

Function: trim (s &key char-bag)

Removes all characters in ‘char-bag‘ (default: whitespaces) at the beginning and end of ‘s‘. If supplied, char-bag has to be a sequence (e.g. string or list of characters).

Examples: (trim " foo ") => "foo"
(trim "+-*foo-bar*-+" :char-bag "+-*") => "foo-bar"
(trim "afood" :char-bag (str:concat "a" "d")) => "foo"

Package

str.

Source

str.lisp.

Function: trim-left (s &key char-bag)

Removes all characters in ‘char-bag‘ (default: whitespaces) at the beginning of ‘s‘. If supplied, char-bag has to be a sequence (e.g. string or list of characters).

Examples: (trim-left " foo ") => "foo "
(trim-right "+-*foo-bar*-+" :char-bag "+-*") => "foo-bar*-+" (trim-left "afood" :char-bag (list #a #d) ;; => "food"

Package

str.

Source

str.lisp.

Function: trim-right (s &key char-bag)

Removes all characters in ‘char-bag‘ (default: whitespaces) at the end of ‘s‘. If supplied, char-bag has to be a sequence (e.g. string or list of characters).

Examples: (trim-right " foo ") => " foo"
(trim-right "+-*foo-bar*-+" :char-bag "+-*") => "+-*foo-bar" (trim-right "afood" :char-bag (list #a #d) ;; => "afoo"

Package

str.

Source

str.lisp.

Function: unlines (strings)

Join the list of strings with a newline character.

Package

str.

Source

str.lisp.

Function: unwords (strings)

Join the list of strings with a whitespace.

Package

str.

Source

str.lisp.

Function: upcase (s)

Return the uppercase version of ‘s’.
Call the built-in ‘string-upcase’, but return nil if ‘s’ is nil (instead of the string "NIL").

Examples:
(upcase "Foo fooF") => "FOO FOOF"
(upcase :foo{foo.f) => "FOO{FOO.F"
(upcase #f) => "F"
(upcase nil) => nil

Package

str.

Source

str.lisp.

Function: upcase? (s)

Return t if all alphabetical characters of ‘s’ are uppercase.

Package

str.

Alias for

upcasep.

Function: upcasep (s)

Return t if all alphabetical characters of ‘s’ are uppercase.

Package

str.

Source

str.lisp.

Function: version ()
Package

str.

Source

str.lisp.

Function: words (s &key limit)

Return list of words, which were delimited by white space. If the optional limit is 0 (the default), trailing empty strings are removed from the result list (see cl-ppcre).

Package

str.

Source

str.lisp.

Function: wrapped-in-p (start/end s)

Does S start and end with ‘START/END’?
If true, return S. Otherwise, return nil.

Example:

(str:wrapped-in-p "/" "/foo/" ;; => "/foo/" (str:wrapped-in-p "/" "/foo" ;; => nil

See also: UIOP:STRING-ENCLOSED-P (prefix s suffix).

Package

str.

Source

str.lisp.


5.2 Internals


5.2.1 Ordinary functions

Function: expand-match-branch (str block patterns forms)

Helper function of the match macro.

Package

str.

Source

str.lisp.

Function: prefix-1 (item1 item2)
Package

str.

Source

str.lisp.

Function: suffix-1 (item1 item2)
Package

str.

Source

str.lisp.


Appendix A Indexes


A.1 Concepts


A.2 Functions

Jump to:   A   B   C   D   E   F   H   I   J   L   M   N   P   R   S   T   U   V   W  
Index Entry  Section

A
add-prefix: Public ordinary functions
add-suffix: Public ordinary functions
alpha?: Public ordinary functions
alphanum?: Public ordinary functions
alphanump: Public ordinary functions
alphap: Public ordinary functions
ascii-char-p: Public ordinary functions
ascii-p: Public ordinary functions

B
blank?: Public ordinary functions
blankp: Public ordinary functions

C
camel-case: Public ordinary functions
capitalize: Public ordinary functions
collapse-whitespaces: Public ordinary functions
common-prefix: Public ordinary functions
concat: Public ordinary functions
constant-case: Public ordinary functions
contains?: Public ordinary functions
containsp: Public ordinary functions
count-substring: Public ordinary functions

D
digit?: Public ordinary functions
digitp: Public ordinary functions
dot-case: Public ordinary functions
downcase: Public ordinary functions
downcase?: Public ordinary functions
downcasep: Public ordinary functions

E
empty?: Public ordinary functions
emptyp: Public ordinary functions
ends-with-p: Public ordinary functions
ends-with?: Public ordinary functions
ensure: Public ordinary functions
ensure-prefix: Public ordinary functions
ensure-suffix: Public ordinary functions
ensure-wrapped-in: Public ordinary functions
expand-match-branch: Private ordinary functions

F
fit: Public ordinary functions
from-file: Public ordinary functions
Function, add-prefix: Public ordinary functions
Function, add-suffix: Public ordinary functions
Function, alpha?: Public ordinary functions
Function, alphanum?: Public ordinary functions
Function, alphanump: Public ordinary functions
Function, alphap: Public ordinary functions
Function, ascii-char-p: Public ordinary functions
Function, ascii-p: Public ordinary functions
Function, blank?: Public ordinary functions
Function, blankp: Public ordinary functions
Function, camel-case: Public ordinary functions
Function, capitalize: Public ordinary functions
Function, collapse-whitespaces: Public ordinary functions
Function, common-prefix: Public ordinary functions
Function, concat: Public ordinary functions
Function, constant-case: Public ordinary functions
Function, contains?: Public ordinary functions
Function, containsp: Public ordinary functions
Function, count-substring: Public ordinary functions
Function, digit?: Public ordinary functions
Function, digitp: Public ordinary functions
Function, dot-case: Public ordinary functions
Function, downcase: Public ordinary functions
Function, downcase?: Public ordinary functions
Function, downcasep: Public ordinary functions
Function, empty?: Public ordinary functions
Function, emptyp: Public ordinary functions
Function, ends-with-p: Public ordinary functions
Function, ends-with?: Public ordinary functions
Function, ensure: Public ordinary functions
Function, ensure-prefix: Public ordinary functions
Function, ensure-suffix: Public ordinary functions
Function, ensure-wrapped-in: Public ordinary functions
Function, expand-match-branch: Private ordinary functions
Function, fit: Public ordinary functions
Function, from-file: Public ordinary functions
Function, has-alpha-p: Public ordinary functions
Function, has-alphanum-p: Public ordinary functions
Function, has-letters-p: Public ordinary functions
Function, header-case: Public ordinary functions
Function, insert: Public ordinary functions
Function, join: Public ordinary functions
Function, letters?: Public ordinary functions
Function, lettersnump: Public ordinary functions
Function, lettersp: Public ordinary functions
Function, lines: Public ordinary functions
Function, no-case: Public ordinary functions
Function, non-blank-string-p: Public ordinary functions
Function, non-empty-string-p: Public ordinary functions
Function, numeric?: Public ordinary functions
Function, numericp: Public ordinary functions
Function, pad: Public ordinary functions
Function, pad-center: Public ordinary functions
Function, pad-left: Public ordinary functions
Function, pad-right: Public ordinary functions
Function, param-case: Public ordinary functions
Function, pascal-case: Public ordinary functions
Function, path-case: Public ordinary functions
Function, prefix: Public ordinary functions
Function, prefix-1: Private ordinary functions
Function, prefix?: Public ordinary functions
Function, prefixp: Public ordinary functions
Function, prune: Public ordinary functions
Function, remove-punctuation: Public ordinary functions
Function, repeat: Public ordinary functions
Function, replace-all: Public ordinary functions
Function, replace-first: Public ordinary functions
Function, replace-using: Public ordinary functions
Function, rsplit: Public ordinary functions
Function, s-assoc-value: Public ordinary functions
Function, s-first: Public ordinary functions
Function, s-last: Public ordinary functions
Function, s-member: Public ordinary functions
Function, s-nth: Public ordinary functions
Function, s-rest: Public ordinary functions
Function, sentence-case: Public ordinary functions
Function, shorten: Public ordinary functions
Function, snake-case: Public ordinary functions
Function, split: Public ordinary functions
Function, split-omit-nulls: Public ordinary functions
Function, starts-with-p: Public ordinary functions
Function, starts-with?: Public ordinary functions
Function, substring: Public ordinary functions
Function, suffix: Public ordinary functions
Function, suffix-1: Private ordinary functions
Function, suffix?: Public ordinary functions
Function, suffixp: Public ordinary functions
Function, swap-case: Public ordinary functions
Function, title-case: Public ordinary functions
Function, to-file: Public ordinary functions
Function, trim: Public ordinary functions
Function, trim-left: Public ordinary functions
Function, trim-right: Public ordinary functions
Function, unlines: Public ordinary functions
Function, unwords: Public ordinary functions
Function, upcase: Public ordinary functions
Function, upcase?: Public ordinary functions
Function, upcasep: Public ordinary functions
Function, version: Public ordinary functions
Function, words: Public ordinary functions
Function, wrapped-in-p: Public ordinary functions

H
has-alpha-p: Public ordinary functions
has-alphanum-p: Public ordinary functions
has-letters-p: Public ordinary functions
header-case: Public ordinary functions

I
insert: Public ordinary functions

J
join: Public ordinary functions

L
letters?: Public ordinary functions
lettersnump: Public ordinary functions
lettersp: Public ordinary functions
lines: Public ordinary functions

M
Macro, match: Public macros
Macro, string-case: Public macros
match: Public macros

N
no-case: Public ordinary functions
non-blank-string-p: Public ordinary functions
non-empty-string-p: Public ordinary functions
numeric?: Public ordinary functions
numericp: Public ordinary functions

P
pad: Public ordinary functions
pad-center: Public ordinary functions
pad-left: Public ordinary functions
pad-right: Public ordinary functions
param-case: Public ordinary functions
pascal-case: Public ordinary functions
path-case: Public ordinary functions
prefix: Public ordinary functions
prefix-1: Private ordinary functions
prefix?: Public ordinary functions
prefixp: Public ordinary functions
prune: Public ordinary functions

R
remove-punctuation: Public ordinary functions
repeat: Public ordinary functions
replace-all: Public ordinary functions
replace-first: Public ordinary functions
replace-using: Public ordinary functions
rsplit: Public ordinary functions

S
s-assoc-value: Public ordinary functions
s-first: Public ordinary functions
s-last: Public ordinary functions
s-member: Public ordinary functions
s-nth: Public ordinary functions
s-rest: Public ordinary functions
sentence-case: Public ordinary functions
shorten: Public ordinary functions
snake-case: Public ordinary functions
split: Public ordinary functions
split-omit-nulls: Public ordinary functions
starts-with-p: Public ordinary functions
starts-with?: Public ordinary functions
string-case: Public macros
substring: Public ordinary functions
suffix: Public ordinary functions
suffix-1: Private ordinary functions
suffix?: Public ordinary functions
suffixp: Public ordinary functions
swap-case: Public ordinary functions

T
title-case: Public ordinary functions
to-file: Public ordinary functions
trim: Public ordinary functions
trim-left: Public ordinary functions
trim-right: Public ordinary functions

U
unlines: Public ordinary functions
unwords: Public ordinary functions
upcase: Public ordinary functions
upcase?: Public ordinary functions
upcasep: Public ordinary functions

V
version: Public ordinary functions

W
words: Public ordinary functions
wrapped-in-p: Public ordinary functions