Introduction

The missing clojure(script) string manipulation library.

La guitarra,
hace llorar a los sueños.
El sollozo de las almas
perdidas,
se escapa por su boca
redonda.
Y como la tarántula
teje una gran estrella
para cazar suspiros,
que flotan en su negro
aljibe de madera.

— Federico García Lorca
Las Seis Cuerdas

Install

Add the following dependency to your project.clj file:

[funcool/cuerdas "2.0.5"]

Quick start

Import the namespace
(ns my.namespace
  (:require [cuerdas.core :as str]))
Use its functions
(str/strip-tags "<p>just <b>some</b> text</p>")
;; => "just some text"

(str/strip-tags "<p>just <b>some</b> text</p>" ["p"])
;; => "just <b>some</b> text"

Functions by Use

Dressing

Add onto or compose strings:

Casing

Convert to and from different casing systems:

The next two convert between ,-moz-transform and MozTransform, respecting leading capitals and dashes:

For casing extremes:

And their locale aware alternatives:

Identification

Identify strings with these boolean returning functions.

Parsing

Convert from strings to other Clojure types.

Low Level

String processing building blocks.

Reference

<<-

Unindent lines. Either strip preceding whitespace automatically or with a user supplied regex.

(str/<<- "first line

            second line (indented)

          another line")

yields the string

first line

  second line (indented)

another line

istr

String interpolation macro. Enables easy string formating allowing symbol substitutions and simple expression evaluation.

(def value 30)

(str/istr "value = ~{value}")
;; => "value = 30"

(str/istr "value = ~(inc value)")
;; => "value = 31"

The istr macro is variadic and allows arbitrary number of arguments that will be concatenated on the final return value:

(str/istr "the value "
          "is ~{value}")
;; => "the value is 30"

alnum?

Checks if a string contains only alphanumeric characters.

(str/alnum? nil)
;; => false

(str/alnum? "")
;; => false

(str/alnum? "Test123")
;; => true

alpha?

Checks if a string contains only alpha characters.

(str/alpha? nil)
;; => false

(str/alpha? " ")
;; => false

(str/alpha? "Test")
;; => true

blank?

Check if the string is empty or contains only whitespaces.

(str/blank? "foobar")
;; => false

(str/blank? "   ")
;; => true

(str/blank? "")
;; => true

(str/blank? nil)
;; => nil

camel

Convert a string or keyword to a camelCased string.

(str/camel "foo bar")
;; => "fooBar"

(str/camel :foo_barBaz)
;; => "fooBarBaz"

(str/camel nil)
;; => nil

capital

Uppercases the first character of a string.

(str/capital "foo")
;; => "Foo"

(str/capital nil)
;; => nil

caseless=

Case insensitive = operator for strings:

(str/caseless= "hello" "HELLO")
;; => true

For locale awareness, use locale-caseless= alternative function.

chars

Returns a seq of char strings from string.

(str/chars "bar")
;; => ["b" "a" "r"]

(str/chars nil)
;; => nil

clean

Trim and replace multiple spaces with a single space.

(str/clean "  a   b   ")
;; => "a b"

(str/clean nil)
;; => nil

collapse-whitespace

Converts any adjacent whitespace characters to a single space.

(str/collapse-whitespace "a\n\nb")
;; => "a b"

(str/collapse-whitespace nil)
;; => nil

css-selector

Convert a JavaScript style selector to CSS style selector

(str/css-selector "PrependedWithDash")
;; => "-prepended-with-dash"

(str/css-selector "noPrependedWithDash")
;; => "no-prepended-with-dash"

(str/css-selector nil)
;; => nil

digits?

Checks if a string contains only digits.

(str/digits? nil)
;; => false

(str/digits? "1.1")
;; => false

(str/digits? "210")
;; => true

empty?

Check if the string is empty.

(str/empty? "foobar")
;; => false

(str/empty? "")
;; => true

(str/empty? " ")
;; => false

(str/empty? nil)
;; => nil

empty-or-nil?

Check if the string is empty or is nil.

(str/empty-or-nil? "foobar")
;; => false

(str/empty-or-nil? nil)
;; => true

(str/empty? "")
;; => true

(str/empty? " ")
;; => false

ends-with?

Check if the string ends with suffix.

Alias: endswith?

(str/ends-with? "foobar" "bar")
;; => true

(str/ends-with? "foobar" nil)
;; => false

(str/ends-with? nil "bar")
;; => false

format

Simple string formatting function.

The string formating works in two main modes: indexed and associative.

The indexed mode is the most simple and consists in using %s tokens in the string indicating the position where interpolation should be done and an arbitrary number of non associate arguments. Format will replace all %s occurrences with the provided values in ordered mode:

(str/format "hello %s and %s" "yen" "ciri")
;; => "hello yen and ciri"

If you don’t provide enough values, the %s tokens won’t be changed:

(str/format "hello %s and %s" "yen")
;; "hello yen and %s"

There are also the associative mode that consists in passing only one associative argument (map or vector) and use named interpolation tokens:

(str/format "hello %(name)s" {:name "yen"})
;; => "hello yen"

A part of the %()s syntax, the $something can be used:

(str/format "hello $name" {:name "yen"})
;; => "hello yen"

And you can access to indexed positions of an vector using $0, $1, $N syntax:

(str/format "hello $0" ["yen"])
;; => "hello yen"

You can use str/fmt as shorter alias to str/format function.

human

Convert a string or keyword to a human friendly string (lower case and spaces).

(str/human "JustNiceForReading")
;; => "just nice for reading"

(str/human :great-for-csv-headers)
;; => "great for csv headers"

(str/human nil)
;; => nil

includes?

Determines whether a string includes a substring.

(str/includes? "foobar" "bar")
;; => true

(str/includes? "foobar" nil)
;; => false

(str/includes? nil nil)
;; => false

join

Join strings together with given separator.

(str/join ["foo" "bar"])
;; => "foobar"

(str/join "," ["foo" "bar"])
;; => "foo,bar"

js-selector

Convert a CSS style selector to JavaScript style selector.

(str/js-selector "-pascal-case-me")
;; => "PascalCaseMe"

(str/js-selector "camel-case-me")
;; => "camelCaseMe"

(str/js-selector nil)
;; => nil

kebab

Convert a string or keyword into a kebab-cased-string.

(str/kebab "Favorite BBQ food")
;; => "favorite-bbq-food"

(str/kebab :favorite-bbq-food)
;; => "favorite-bbq-food"

(str/kebab nil)
;; => nil

keyword

A more helpful and forgiving version of clojure.core/keyword.

(str/keyword "just_doIt Right")
;; => :just-do-it-right

(str/keyword "foo" "auto namespace me")
;; => :foo/auto-namespace-me

;; and assuming the user namespace
(str/keyword *ns* "auto namespace me")
;; => :user/auto-namespace-me

(str/keyword nil)
;; => nil

letters?

This is an unicode aware version of alpha?.

(str/letters? nil)
;; => false

(str/letters? " ")
;; => false

(str/letters? "Test")
;; => true

(str/letters? "Русский")
;; => true

lines

Return a list of the lines in the string.

(str/lines "foo\nbar")
;; => ["foo" "bar"]

(str/lines nil)
;; => nil

lower

Convert a string to all lower-case in a locale independent manner:

(str/lower "FOO")
;; => "foo"

(str/lower nil)
;; => nil

For locale awareness, use locale-lower alternative function.

ltrim

Removes whitespace or specified characters from left side of string.

Alias: lstrip

(str/ltrim " foo ")
;; => "foo "

(str/ltrim "-foo-", "-")
;; => "foo-"

(str/ltrim nil)
;; => nil

numeric?

Checks if a string contains only numeric characters.

(str/numeric? nil)
;; => false

(str/numeric? "1.1")
;; => true

(str/numeric? "2e10")
;; => true

pad

Pads the string with characters until the total string length is equal to the passed length parameter.

By default, pads on the left with the space char.

(str/pad "1" {:length 8})
;; => "       1"

(str/pad nil {:length 8})
;; => nil

(str/pad "1" {:length 8 :padding "0"})
;; => "00000001"

(str/pad "1" {:length 8 :padding "0" :type :right})
;; => "10000000"

(str/pad "1" {:length 8 :padding "0" :type :both})
;; => "00001000"

parse-double

Parses string into a double:

(str/parse-double "1.4")
;; => 1.4

(str/parse-double nil)
;; => NaN

parse-int

Parses string into a integer:

(str/parse-int "1.4")
;; => 1

(str/parse-int nil)
;; => NaN

parse-number

General purpose function for parse number like strings to number. It works with integers and floats.

(str/parse-number "1.4")
;; => 1

(str/parse-number "1.4")
;; => 1.4

(str/parse-number "1")
;; => 1

(str/parse-number "")
;; => NaN

pascal

Convert a string or keyword into a PascalCasedString (aka, UpperCamelCase and ClassCase).

(str/pascal "my name is epeli")
;; => "MyNameIsEpeli"

(str/pascal :some-record)
;; => "SomeRecord"

(str/pascal nil)
;; => nil

phrase

Convert a potentially mixed string or keyword into a capitalized, spaced string

(str/phrase "  capitalize dash-CamelCase_underscore trim  ")
;; => "Capitalize dash camel case underscore trim"

(str/phrase :nobody-uses-keywords-this-long-but-it-still-works)
;; => "Nobody uses keywords this long but it still works"

(str/phrase nil)
;; => nil

prune

Truncates a string to certain width and adds "…​" if necessary. Making sure that the pruned string does not exceed the original length and avoid half-chopped words when truncating.

(str/prune "Hello World" 5)
;; => "Hello..."

(str/prune "Hello World" 8)
;; => "Hello..."

(str/prune "Hello World" 11 " (...)")
;; => "Hello (...)"

(str/prune nil 5)
;; => nil

quote

Quote a string.

(str/quote "a")
;; => "\"a\""

(str/quote nil)
;; => nil

repeat

Repeats string N times.

(str/repeat "a" 3)
;; => "aaa"

(str/repeat nil 3)
;; => nil

replace

Replaces all instances of match with replacement in s.

(str/replace "aa bb aa" "aa" "kk")
;; => "kk bb kk"

(str/replace "aa bb aa" #"aa" "kk")
;; => "kk bb kk"

(str/replace nil #"aa" "kk")
;; => nil

replace-first

Replaces first instance of match with replacement in s.

(str/replace-first "aa bb aa" "aa" "kk")
;; => "kk bb aa"

(str/replace-first "aa bb aa" #"aa" "kk")
;; => "kk bb aa"

(str/replace-first nil #"aa" "kk")
;; => nil

reverse

Return string reverted

(str/reverse "bar")
;; => "rab"

(str/reverse nil)
;; => nil

rtrim

Removes whitespace or specified characters from right side of string.

Alias: rstrip

(str/rtrim " foo ")
;; => " foo"

(str/rtrim "-foo-", "-")
;; => "-foo"

(str/rtrim nil)
;; => nil

slice

Extracts a section of a string and returns a new string.

(str/slice "123" 1)
;; => "23"

(str/slice "1234" 1 3)
;; => "23"

(str/slice nil 1 3)
;; => nil

slug

Transforms string or keyword into URL slug.

(str/slug "Un éléphant à l'orée du bois")
;; => "un-elephant-a-loree-du-bois"

(str/slug nil)
;; => nil

Traditionally, slug is consisted in ascii characters, but in modern ages, the URL and domain names already supports unicode characters. The uslug is more modern version of slug function that respects the unicode characters.

snake

Convert a string or keyword to a snake_cased_string.

(str/snake "Slither-sliter Slither")
;; => "slither_slither_slither"

(str/snake :slither-slither)
;; => "slither_slither"

(str/snake nil)
;; => nil

split

Splits a string on a separator a limited number of times. The separator can be a string or RegExp instance.

(str/split "1 2 3")
;; => ["1" "2" "3"]

(str/split "1 2 3" " ")
;; => ["1" "2" "3"])

(str/split "1 2 3" #"\s")
;; => ["1" "2" "3"]

(str/split "1 2 3" #"\s" 2)
;; => ["1" "2 3"]

(str/split nil)
;; => nil

starts-with?

Check if the string starts with prefix.

Alias: startswith?

(str/starts-with? "foobar" "foo")
;; => true

(str/starts-with? "foobar" nil)
;; => false

(str/starts-with? nil "foo")
;; => false

strip-newlines

Takes a string and replaces newlines with a space. Multiple lines are replaced with a single space.

(str/strip-newlines "a\n\nb")
;; => "a b"

(str/strip-newlines nil)
;; => nil

strip-prefix

Remove prefix from string if it matches exactly or leave the string untouched.

(str/strip-prefix nil nil)
;; => nil

(str/strip-prefix "a" nil)
;; => "a"

(str/strip-prefix "-=a" "-=")
;; => "a"

strip-suffix

Remove suffix from string if it matches exactly or leave the string untouched.

(str/strip-suffix nil nil)
;; => nil

(str/strip-suffix "a" nil)
;; => "a"

(str/strip-suffix "a=-" "=-")
;; => "a"

strip-tags

Remove html tags from string.

(str/strip-tags "<p>just <b>some</b> text</p>")
;; => "just some text"

(str/strip-tags "<p>just <b>some</b> text</p>" ["p"])
;; => "just <b>some</b> text"

(str/strip-tags nil)
;; => nil

It also allows arbitrary replacements:

(str/strip-tags "<p>just<br>text</p>" {:br "\n"})
;; => "just\ntext"

(str/strip-tags "<p>just<br>text</p>" ["br"] {:br "\n"})
;; => "<p>just\ntext</p>"

surround

Surround a string with another string.

(str/surround "a" "-")
;; => "-a-"

(str/surround "a" "-^-")
;; => "-^-a-^-"

(str/surround nil "-^-")
;; => nil

title

Convert a string or keyword into a space separated string with each word capitalized.

(str/title "a tale of two cities")
;; => "A Tale Of Two Cities"

(str/title :title-case)
;; => "Title Case"

(str/title nil)
;; => nil

to-bool

Returns true for 1/on/true/yes string values (case-insensitive), false otherwise.

(str/to-bool "hello")
;; => false

(str/to-bool "on")
;; => true

trim

Removes whitespace or specified characters from both ends of string.

Alias: strip

(str/trim " foo ")
;; => "foo"

(str/trim "-foo-", "-")
;; => "foo"

(str/trim nil)
;; => nil

unlines

Joins a list of strings with a newline separator. This operation is the opposite of lines.

(str/unlines ["foo" "nbar"])
;; => "foo\nbar"

(str/unlines nil)
;; => nil

unquote

Unquote a string.

(str/unquote "\"a\"")
;; => "a"

(str/unquote nil)
;; => nil

unsurround

Unsurround a string surrounded by another.

(str/unsurround "-a-" "-")
;; => "a"

(str/unsurround "-^-a-^-" "-^-")
;; => "a"

(str/unsurround nil "-")
;; => nil

upper

Convert a string to all upper-case in a locale independent manner:

(str/upper "foobar")
;; => "FOOBAR"

(str/upper nil)
;; => nil

For locale awareness, use locale-upper alternative function.

word?

This is a unicode aware version of alnum?.

(str/word? nil)
;; => false

(str/word? "")
;; => false

(str/word? "Русский222")
;; => true

words

Returns a vector of the words in the string. Can be provided with a regular expression that matches a single word (defaults to [a-zA-Z0-9_-]+).

(str/words nil)
;; => nil

(str/words "foo, bar")
;; => ["foo" "bar"]

(str/words "foo, bar." #"[^, ]+")
;; => ["foo" "bar."]

Run tests

cuerdas has targeted some parts of implementation for Clojure and ClojureScript using Reader Conditionals.

Run tests in the Clojure environment using Leiningen.
$ lein test cuerdas.core-tests
Compile ClojureScript to JavaScript.
$ ./scripts/build
Run tests on compiled ClojureScript using node.
$ node ./out/tests.js

How to Contribute?

cuerdas' source is on github.

Unlike Clojure and other Clojure contrib libs, cuerdas does not have many restrictions for contributions.

Pull requests are welcome!

License

cuerdas is licensed under BSD (2-Clause) license:

Copyright (c) 2015-2016 Andrey Antukh <niwi@niwi.nz>

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.