18.3 String Construction and Manipulation

Most of the interesting operations on strings may be performed with the generic sequence functions described in chapter 14. The following functions perform additional operations that are specific to strings.

Note that this remark, predating the design of the Common Lisp Object System, uses the term “generic” in a generic sense and not necessarily in the technical sense used by CLOS (see chapter 2).

[Function] make-string size &key :initial-element :element-type

This returns a simple string of length size, each of whose characters has been initialized to the :initial-element argument. If an :initial-element argument is not specified, then the string will be initialized in an implementation-dependent way.

The :element-type argument names the type of the elements of the string; a string is constructed of the most specialized type that can accommodate elements of the given type. If :element-type is omitted, the type character is the default.

X3J13 voted in January 1989 to clarify that the size argument must be a non-negative integer less than the value of array-dimension-limit.


[Function] string-trim character-bag string
[Function] string-left-trim character-bag string
[Function] string-right-trim character-bag string

string-trim returns a substring of string, with all characters in character-bag stripped off the beginning and end. The function string-left-trim is similar but strips characters off only the beginning; string-right-trim strips off only the end. The argument character-bag may be any sequence containing characters. For example:

(string-trim ’(#\Space #\Tab #\Newline) " garbanzo beans
        ")  "garbanzo beans"
(string-trim " (*)" " ( *three (silly) words* ) ")
    "three (silly) words"
(string-left-trim " (*)" " ( *three (silly) words* ) ")
    "three (silly) words* ) "
(string-right-trim " (*)" " ( *three (silly) words* ) ")
    " ( *three (silly) words"

If no characters need to be trimmed from the string, then either the argument string itself or a copy of it may be returned, at the discretion of the implementation.

X3J13 voted in June 1989 to clarify string coercion (see string).


[Function] string-upcase string &key :start :end
[Function] string-downcase string &key :start :end
[Function] string-capitalize string &key :start :end

string-upcase returns a string just like string with all lowercase characters replaced by the corresponding uppercase characters. More precisely, each character of the result string is produced by applying the function char-upcase to the corresponding character of string.

string-downcase is similar, except that uppercase characters are converted to lowercase characters (using char-downcase).

The keyword arguments :start and :end delimit the portion of the string to be affected. The result is always of the same length as string, however.

The argument is not destroyed. However, if no characters in the argument require conversion, the result may be either the argument or a copy of it, at the implementation’s discretion. For example:

(string-upcase "Dr. Livingstone, I presume?")
    "DR. LIVINGSTONE, I PRESUME?"
(string-downcase "Dr. Livingstone, I presume?")
    "dr. livingstone, i presume?"
(string-upcase "Dr. Livingstone, I presume?" :start 6 :end 10)
    "Dr. LiVINGstone, I presume?"

string-capitalize produces a copy of string such that, for every word in the copy, the first character of the word, if case-modifiable, is uppercase and any other case-modifiable characters in the word are lowercase. For the purposes of string-capitalize, a word is defined to be a consecutive subsequence consisting of alphanumeric characters or digits, delimited at each end either by a non-alphanumeric character or by an end of the string. For example:

(string-capitalize " hello ")  " Hello "
(string-capitalize
    "occlUDeD cASEmenTs FOreSTAll iNADVertent DEFenestraTION")
"Occluded Casements Forestall Inadvertent Defenestration"
(string-capitalize ’kludgy-hash-search)  "Kludgy-Hash-Search"
(string-capitalize "DON’T!")  "Don’T!"     ;not "Don’t!"
(string-capitalize "pipe 13a, foo16c")  "Pipe 13a, Foo16c"

X3J13 voted in June 1989 to clarify string coercion (see string).


[Function] nstring-upcase string &key :start :end
[Function] nstring-downcase string &key :start :end
[Function] nstring-capitalize string &key :start :end

These three functions are just like string-upcase, string-downcase, and string-capitalize but destructively modify the argument string by altering case-modifiable characters as necessary.

The keyword arguments :start and :end delimit the portion of the string to be affected. The argument string is returned as the result.


[Function] string x

Most of the string functions effectively apply string to such of their arguments as are supposed to be strings. If x is a string, it is returned. If x is a symbol, its print name is returned.

In any other situation, an error is signaled.

To convert a sequence of characters to a string, use coerce. (Note that (coerce x ’string) will not succeed if x is a symbol. Conversely, string will not convert a list or other sequence to be a string.)

To get the string representation of a number or any other Lisp object, use prin1-to-string, princ-to-string, or format.

X3J13 voted in June 1989 to specify that the following functions perform coercion on their string arguments identical to that performed by the function string.

string=  string-equal string-trim
string<  string-lessp string-left-trim
string>  string-greaterp string-right-trim
string<= string-not-greaterpstring-upcase
string>= string-not-lessp string-downcase
string/=  string-not-equal string-capitalize

Note that nstring-upcase, nstring-downcase, and nstring-capitalize are absent from this list; because they modify destructively, the argument must be a string.

As part of the same vote X3J13 specified that string may perform additional implementation-dependent coercions but the returned value must be of type string. Only when no coercion is defined, whether standard or implementation-dependent, is string required to signal an error, in which case the error condition must be of type type-error.