Common Lisp the Language, 2nd Edition

Next: Structures Up: Strings Previous: String Comparison

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

This returns a string (in fact 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.

Implementation note: It may be convenient to initialize the string to null characters, or to spaces, or to garbage (``whatever was there'').

A string is really just a one-dimensional array of ``string characters'' (that is, those characters that are members of type `string-char`). More complex character arrays may be constructed using the function `make-array`.

X3J13 voted in March 1989 (CHARACTER-PROPOSAL) to eliminate the type `string-char` and to add a keyword argument `:element-type` to `make-string`. The new function description is as follows.

[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 (ARGUMENTS-UNDERSPECIFIED) 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
``string-left-trim character-bag string
``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 (STRING-COERCION) to clarify string coercion (see `string`).

[Function]
`string-upcase string &key :start :end
``string-downcase string &key :start :end
``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 (STRING-COERCION) to clarify string coercion (see `string`).

Compatibility note: Some very approximate Interlisp equivalents to `string-upcase`, `string-downcase`, and `string-capitalize` are `u-case`, `l-case` with second argument `nil`, and `l-case` with second argument `t`.

[Function]
`nstring-upcase string &key :start :end
``nstring-downcase string &key :start :end
``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.

If x is a string character (a character of type `string-char`), then a string containing that one character is returned.

X3J13 voted in March 1989 (CHARACTER-PROPOSAL) to eliminate the type `string-char` and to redefine the type `string` to be the union of one or more specialized vector types, the types of whose elements are subtypes of the type `character`. Presumably converting a character to a string always works according to this vote.

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 (STRING-COERCION) 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-greaterp    string-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`.

Next: Structures Up: Strings Previous: String Comparison