On this page:
4.4.1 String Constructors, Selectors, and Mutators
string?
make-string
string
string->immutable-string
string-length
string-ref
string-set!
substring
string-copy
string-copy!
string-fill!
string-append
string-append-immutable
string->list
list->string
build-string
4.4.2 String Comparisons
string=?
string<?
string<=?
string>?
string>=?
string-ci=?
string-ci<?
string-ci<=?
string-ci>?
string-ci>=?
4.4.3 String Conversions
string-upcase
string-downcase
string-titlecase
string-foldcase
string-normalize-nfd
string-normalize-nfkd
string-normalize-nfc
string-normalize-nfkc
4.4.4 Locale-Specific String Operations
string-locale=?
string-locale<?
string-locale>?
string-locale-ci=?
string-locale-ci<?
string-locale-ci>?
string-locale-upcase
string-locale-downcase
4.4.5 String Grapheme Clusters
string-grapheme-span
string-grapheme-count
4.4.6 Additional String Functions
string-append*
string-join
string-normalize-spaces
string-replace
string-split
string-trim
non-empty-string?
string-find
string-contains?
string-prefix?
string-suffix?
4.4.7 Converting Values to Strings
~a
~v
~s
~e
~r
~.a
~.v
~.s

4.4 Strings🔗ℹ

+Strings (Unicode) in The Racket Guide introduces strings.

A string is a fixed-length array of characters.

A string can be mutable or immutable. When an immutable string is provided to a procedure like string-set!, the exn:fail:contract exception is raised. String constants generated by the default reader (see Reading Strings) are immutable, and they are interned in read-syntax mode. Use immutable? to check whether a string is immutable.

Two strings are equal? when they have the same length and contain the same sequence of characters.

A string can be used as a single-valued sequence (see Sequences). The characters of the string serve as elements of the sequence. See also in-string.

See Reading Strings for information on reading strings and Printing Strings for information on printing strings.

See also: immutable?, symbol->string, bytes->string/utf-8.

4.4.1 String Constructors, Selectors, and Mutators🔗ℹ

procedure

(string? v)  boolean?

  v : any/c
Returns #t if v is a string, #f otherwise.

See also immutable-string? and mutable-string?.

Examples:
> (string? "Apple")

#t

> (string? 'apple)

#f

procedure

(make-string k [char])  string?

  k : exact-nonnegative-integer?
  char : char? = #\nul
Returns a new mutable string of length k where each position in the string is initialized with the character char.

Example:
> (make-string 5 #\z)

"zzzzz"

procedure

(string char ...)  string?

  char : char?
Returns a new mutable string whose length is the number of provided chars, and whose positions are initialized with the given chars.

Example:
> (string #\A #\p #\p #\l #\e)

"Apple"

procedure

(string->immutable-string str)  (and/c string? immutable?)

  str : string?
Returns an immutable string with the same content as str, returning str itself if str is immutable.

Examples:
> (immutable? (string #\H #\e #\l #\l #\o))

#f

> (immutable? (string->immutable-string (string #\H #\e #\l #\l #\o)))

#t

procedure

(string-length str)  exact-nonnegative-integer?

  str : string?
Returns the length of str.

Example:
> (string-length "Apple")

5

procedure

(string-ref str k)  char?

  str : string?
  k : exact-nonnegative-integer?
Returns the character at position k in str. The first position in the string corresponds to 0, so the position k must be less than the length of the string, otherwise the exn:fail:contract exception is raised.

Example:
> (string-ref "Apple" 0)

#\A

procedure

(string-set! str k char)  void?

  str : (and/c string? (not/c immutable?))
  k : exact-nonnegative-integer?
  char : char?
Changes the character position k in str to char. The first position in the string corresponds to 0, so the position k must be less than the length of the string, otherwise the exn:fail:contract exception is raised.

Examples:
> (define s (string #\A #\p #\p #\l #\e))
> (string-set! s 4 #\y)
> s

"Apply"

procedure

(substring str start [end])  string?

  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer? = (string-length str)
Returns a new mutable string that is (- end start) characters long, and that contains the same characters as str from start inclusive to end exclusive. The first position in a string corresponds to 0, so the start and end arguments must be less than or equal to the length of str, and end must be greater than or equal to start, otherwise the exn:fail:contract exception is raised.

Examples:
> (substring "Apple" 1 3)

"pp"

> (substring "Apple" 1)

"pple"

procedure

(string-copy str)  string?

  str : string?
Returns (substring str 0).

Examples:
> (define s1 "Yui")
> (define pilot (string-copy s1))
> (list s1 pilot)

'("Yui" "Yui")

> (for ([i (in-naturals)] [ch '(#\R #\e #\i)])
    (string-set! pilot i ch))
> (list s1 pilot)

'("Yui" "Rei")

procedure

(string-copy! dest    
  dest-start    
  src    
  [src-start    
  src-end])  void?
  dest : (and/c string? (not/c immutable?))
  dest-start : exact-nonnegative-integer?
  src : string?
  src-start : exact-nonnegative-integer? = 0
  src-end : exact-nonnegative-integer? = (string-length src)
Changes the characters of dest starting at position dest-start to match the characters in src from src-start (inclusive) to src-end (exclusive), where the first position in a string corresponds to 0. The strings dest and src can be the same string, and in that case the destination region can overlap with the source region; the destination characters after the copy match the source characters from before the copy. If any of dest-start, src-start, or src-end are out of range (taking into account the sizes of the strings and the source and destination regions), the exn:fail:contract exception is raised.

Examples:
> (define s (string #\A #\p #\p #\l #\e))
> (string-copy! s 4 "y")
> (string-copy! s 0 s 3 4)
> s

"lpply"

procedure

(string-fill! dest char)  void?

  dest : (and/c string? (not/c immutable?))
  char : char?
Changes dest so that every position in the string is filled with char.

Examples:
> (define s (string #\A #\p #\p #\l #\e))
> (string-fill! s #\q)
> s

"qqqqq"

procedure

(string-append str ...)  string?

  str : string?
Returns a new mutable string that is as long as the sum of the given strs’ lengths, and that contains the concatenated characters of the given strs. If no strs are provided, the result is a zero-length string.

Example:
> (string-append "Apple" "Banana")

"AppleBanana"

procedure

(string-append-immutable str ...)  (and/c string? immutable?)

  str : string?
The same as string-append, but the result is an immutable string.

Examples:
> (string-append-immutable "Apple" "Banana")

"AppleBanana"

> (immutable? (string-append-immutable "A" "B"))

#t

Added in version 7.5.0.14 of package base.

procedure

(string->list str)  (listof char?)

  str : string?
Returns a new list of characters corresponding to the content of str. That is, the length of the list is (string-length str), and the sequence of characters in str is the same sequence in the result list.

Example:
> (string->list "Apple")

'(#\A #\p #\p #\l #\e)

procedure

(list->string lst)  string?

  lst : (listof char?)
Returns a new mutable string whose content is the list of characters in lst. That is, the length of the string is (length lst), and the sequence of characters in lst is the same sequence in the result string.

Example:
> (list->string (list #\A #\p #\p #\l #\e))

"Apple"

procedure

(build-string n proc)  string?

  n : exact-nonnegative-integer?
  proc : (exact-nonnegative-integer? . -> . char?)
Creates a string of n characters by applying proc to the integers from 0 to (sub1 n) in order. If str is the resulting string, then (string-ref str i) is the character produced by (proc i).

Example:
> (build-string 5 (lambda (i) (integer->char (+ i 97))))

"abcde"

4.4.2 String Comparisons🔗ℹ

procedure

(string=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Returns #t if all of the arguments are equal?.

Examples:
> (string=? "Apple" "apple")

#f

> (string=? "a" "as" "a")

#f

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string<? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Returns #t if the arguments are lexicographically sorted increasing, where individual characters are ordered by char<?, #f otherwise.

Examples:
> (string<? "Apple" "apple")

#t

> (string<? "apple" "Apple")

#f

> (string<? "a" "b" "c")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string<=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string<?, but checks whether the arguments are nondecreasing.

Examples:
> (string<=? "Apple" "apple")

#t

> (string<=? "apple" "Apple")

#f

> (string<=? "a" "b" "b")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string>? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string<?, but checks whether the arguments are decreasing.

Examples:
> (string>? "Apple" "apple")

#f

> (string>? "apple" "Apple")

#t

> (string>? "c" "b" "a")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string>=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string<?, but checks whether the arguments are nonincreasing.

Examples:
> (string>=? "Apple" "apple")

#f

> (string>=? "apple" "Apple")

#t

> (string>=? "c" "b" "b")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-ci=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Returns #t if all of the arguments are equal? after locale-insensitive case-folding via string-foldcase.

Examples:
> (string-ci=? "Apple" "apple")

#t

> (string-ci=? "a" "a" "a")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-ci<? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string<?, but checks whether the arguments would be in increasing order if each was first case-folded using string-foldcase (which is locale-insensitive).

Examples:
> (string-ci<? "Apple" "apple")

#f

> (string-ci<? "apple" "banana")

#t

> (string-ci<? "a" "b" "c")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-ci<=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string-ci<?, but checks whether the arguments would be nondecreasing after case-folding.

Examples:
> (string-ci<=? "Apple" "apple")

#t

> (string-ci<=? "apple" "Apple")

#t

> (string-ci<=? "a" "b" "b")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-ci>? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string-ci<?, but checks whether the arguments would be decreasing after case-folding.

Examples:
> (string-ci>? "Apple" "apple")

#f

> (string-ci>? "banana" "Apple")

#t

> (string-ci>? "c" "b" "a")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-ci>=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string-ci<?, but checks whether the arguments would be nonincreasing after case-folding.

Examples:
> (string-ci>=? "Apple" "apple")

#t

> (string-ci>=? "apple" "Apple")

#t

> (string-ci>=? "c" "b" "b")

#t

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

4.4.3 String Conversions🔗ℹ

procedure

(string-upcase str)  string?

  str : string?
Returns a string whose characters are the upcase conversion of the characters in str. The conversion uses Unicode’s locale-independent conversion rules that map code-point sequences to code-point sequences (instead of simply mapping a 1-to-1 function on code points over the string), so the string produced by the conversion can be longer than the input string.

Examples:
> (string-upcase "abc!")

"ABC!"

> (string-upcase "Straße")

"STRASSE"

procedure

(string-downcase string)  string?

  string : string?
Like string-upcase, but the downcase conversion.

Examples:
> (string-downcase "aBC!")

"abc!"

> (string-downcase "Straße")

"straße"

> (string-downcase "ΚΑΟΣ")

"καος"

> (string-downcase "Σ")

"σ"

procedure

(string-titlecase string)  string?

  string : string?
Like string-upcase, but the titlecase conversion only for the first character in each sequence of cased characters in str (ignoring case-ignorable characters).

Examples:
> (string-titlecase "aBC  twO")

"Abc  Two"

> (string-titlecase "y2k")

"Y2k"

> (string-titlecase "main straße")

"Main Straße"

> (string-titlecase "stra ße")

"Stra Sse"

procedure

(string-foldcase string)  string?

  string : string?
Like string-upcase, but the case-folding conversion.

Examples:
> (string-foldcase "aBC!")

"abc!"

> (string-foldcase "Straße")

"strasse"

> (string-foldcase "ΚΑΟΣ")

"καοσ"

procedure

(string-normalize-nfd string)  string?

  string : string?
Returns a string that is the Unicode normalized form D of string. If the given string is already in the corresponding Unicode normal form, the string may be returned directly as the result (instead of a newly allocated string).

Example:
> (equal? (string-normalize-nfd "Ç") "Ç")

#t

procedure

(string-normalize-nfkd string)  string?

  string : string?
Like string-normalize-nfd, but for normalized form KD.

Example:
> (equal? (string-normalize-nfkd "ℌ") "H")

#t

procedure

(string-normalize-nfc string)  string?

  string : string?
Like string-normalize-nfd, but for normalized form C.

Example:
> (equal? (string-normalize-nfc "Ç") "Ç")

#t

procedure

(string-normalize-nfkc string)  string?

  string : string?
Like string-normalize-nfd, but for normalized form KC.

Example:
> (equal? (string-normalize-nfkc "ℋ̧") "Ḩ")

#t

4.4.4 Locale-Specific String Operations🔗ℹ

procedure

(string-locale=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string=?, but the strings are compared in a locale-specific way, based on the value of current-locale. See Encodings and Locales for more information on locales.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-locale<? str1 str2 ...+)  boolean?

  str1 : string?
  str2 : string?
Like string<?, but the sort order compares strings in a locale-specific way, based on the value of current-locale. In particular, the sort order may not be simply a lexicographic extension of character ordering.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-locale>? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string>?, but locale-specific like string-locale<?.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-locale-ci=? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string-locale=?, but strings are compared using rules that are both locale-specific and case-insensitive (depending on what “case-insensitive” means for the current locale).

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-locale-ci<? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string<?, but both locale-sensitive and case-insensitive like string-locale-ci=?.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-locale-ci>? str1 str2 ...)  boolean?

  str1 : string?
  str2 : string?
Like string>?, but both locale-sensitive and case-insensitive like string-locale-ci=?.

Changed in version 7.0.0.13 of package base: Allow one argument, in addition to allowing two or more.

procedure

(string-locale-upcase string)  string?

  string : string?
Like string-upcase, but using locale-specific case-conversion rules based on the value of current-locale.

procedure

(string-locale-downcase string)  string?

  string : string?
Like string-downcase, but using locale-specific case-conversion rules based on the value of current-locale.

4.4.5 String Grapheme Clusters🔗ℹ

procedure

(string-grapheme-span str start [end])  exact-nonnegative-integer?

  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer? = (string-length str)
Returns the number of characters (i.e., code points) in the string that form a Unicode grapheme cluster starting at start, assuming that start is the start of a grapheme cluster and extending no further than the character before end. The result is 0 if start equals end.

The start and end arguments must be valid indices as for substring, otherwise the exn:fail:contract exception is raised.

See also char-grapheme-cluster-step.

Examples:
> (string-grapheme-span "" 0)

0

> (string-grapheme-span "a" 0)

1

> (string-grapheme-span "ab" 0)

1

> (string-grapheme-span "\r\n" 0)

2

> (string-grapheme-span "\r\nx" 0)

2

> (string-grapheme-span "\r\nx" 2)

1

> (string-grapheme-span "\r\nx" 0 1)

1

Added in version 8.6.0.2 of package base.

procedure

(string-grapheme-count str start [end])

  exact-nonnegative-integer?
  str : string?
  start : exact-nonnegative-integer?
  end : exact-nonnegative-integer? = (string-length str)
Returns the number of grapheme clusters in (substring str start end).

The start and end arguments must be valid indices as for substring, otherwise the exn:fail:contract exception is raised.

Examples:

Added in version 8.6.0.2 of package base.

4.4.6 Additional String Functions🔗ℹ

 (require racket/string) package: base
The bindings documented in this section are provided by the racket/string and racket libraries, but not racket/base.

procedure

(string-append* str ... strs)  string?

  str : string?
  strs : (listof string?)
Like string-append, but the last argument is used as a list of arguments for string-append, so (string-append* str ... strs) is the same as (apply string-append str ... strs). In other words, the relationship between string-append and string-append* is similar to the one between list and list*.

Examples:
> (string-append* "a" "b" '("c" "d"))

"abcd"

> (string-append* (cdr (append* (map (lambda (x) (list ", " x))
                                     '("Alpha" "Beta" "Gamma")))))

"Alpha, Beta, Gamma"

procedure

(string-join strs    
  [sep    
  #:before-first before-first    
  #:before-last before-last    
  #:after-last after-last])  string?
  strs : (listof string?)
  sep : string? = " "
  before-first : string? = ""
  before-last : string? = sep
  after-last : string? = ""
Appends the strings in strs, inserting sep between each pair of strings in strs. before-last, before-first, and after-last are analogous to the inputs of add-between: they specify an alternate separator between the last two strings, a prefix string, and a suffix string respectively.

Examples:
> (string-join '("one" "two" "three" "four"))

"one two three four"

> (string-join '("one" "two" "three" "four") ", ")

"one, two, three, four"

> (string-join '("one" "two" "three" "four") " potato ")

"one potato two potato three potato four"

> (string-join '("x" "y" "z") ", "
               #:before-first "Todo: "
               #:before-last " and "
               #:after-last ".")

"Todo: x, y and z."

procedure

(string-normalize-spaces str    
  [sep    
  space    
  #:trim? trim?    
  #:repeat? repeat?])  string?
  str : string?
  sep : (or/c string? regexp?) = #px"\\s+"
  space : string? = " "
  trim? : any/c = #t
  repeat? : any/c = #f
Normalizes spaces in the input str by trimming it (using string-trim and sep) and replacing all whitespace sequences in the result with space, which defaults to a single space.

Example:
> (string-normalize-spaces "  foo bar  baz \r\n\t")

"foo bar baz"

The result of (string-normalize-spaces str sep space) is the same as (string-join (string-split str sep ....) space).

procedure

(string-replace str from to [#:all? all?])  string?

  str : string?
  from : (or/c string? regexp?)
  to : string?
  all? : any/c = #t
Returns str with all occurrences of from replaced with by to. If from is a string, it is matched literally (as opposed to being used as a regular expression).

By default, all occurrences are replaced, but only the first match is replaced if all? is #f.

Example:
> (string-replace "foo bar baz" "bar" "blah")

"foo blah baz"

procedure

(string-split str    
  [sep    
  #:trim? trim?    
  #:repeat? repeat?])  (listof string?)
  str : string?
  sep : (or/c string? regexp?) = #px"\\s+"
  trim? : any/c = #t
  repeat? : any/c = #f
Splits the input str on sep, returning a list of substrings of str that are separated by sep, defaulting to splitting the input on whitespaces. The input is first trimmed using sep (see string-trim), unless trim? is #f. Empty matches are handled in the same way as for regexp-split. As a special case, if str is the empty string after trimming, the result is '() instead of '("").

Like string-trim, provide sep to use a different separator, and repeat? controls matching repeated sequences.

Examples:
> (string-split "  foo bar  baz \r\n\t")

'("foo" "bar" "baz")

> (string-split "  ")

'()

> (string-split "  " #:trim? #f)

'("" "")

procedure

(string-trim str    
  [sep    
  #:left? left?    
  #:right? right?    
  #:repeat? repeat?])  string?
  str : string?
  sep : (or/c string? regexp?) = #px"\\s+"
  left? : any/c = #t
  right? : any/c = #t
  repeat? : any/c = #f
Trims the input str by removing prefix and suffix sep, which defaults to whitespace. A string sep is matched literally (as opposed to being used as a regular expression).

Use #:left? #f or #:right? #f to suppress trimming the corresponding side. When repeat? is #f (the default), only one match is removed from each side; when repeat? is true, all initial or trailing matches are trimmed (which is an alternative to using a regular expression sep that contains +).

Examples:
> (string-trim "  foo bar  baz \r\n\t")

"foo bar  baz"

> (string-trim "  foo bar  baz \r\n\t" " " #:repeat? #t)

"foo bar  baz \r\n\t"

> (string-trim "aaaxaayaa" "aa")

"axaay"

procedure

(non-empty-string? x)  boolean?

  x : any/c
Returns #t if x is a string and is not empty; returns #f otherwise.

Added in version 6.3 of package base.

procedure

(string-find s contained)  (or/c exact-nonnegative-integer? #f)

  s : string?
  contained : string?

procedure

(string-contains? s contained)  boolean?

  s : string?
  contained : string?

procedure

(string-prefix? s prefix)  boolean?

  s : string?
  prefix : string?

procedure

(string-suffix? s suffix)  boolean?

  s : string?
  suffix : string?
Checks whether s includes at any location, starts with, or ends with the second argument, respectively. The string-find function returns the first position within s where contained is found, if any, while string-contains? reports only whether it was found.

Examples:
> (string-prefix? "Racket" "R")

#t

> (string-prefix? "Jacket" "R")

#f

> (string-suffix? "Racket" "et")

#t

> (string-find "Racket" "ack")

1

> (string-contains? "Racket" "ack")

#t

Added in version 6.3 of package base.
Changed in version 8.15.0.7: Added string-find.

4.4.7 Converting Values to Strings🔗ℹ

 (require racket/format) package: base
The bindings documented in this section are provided by the racket/format and racket libraries, but not racket/base.

The racket/format library provides functions for converting Racket values to strings. In addition to features like padding and numeric formatting, the functions have the virtue of being shorter than format (with format string), number->string, or string-append.

procedure

(~a v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = ""
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = ""
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string
Converts each v to a string in display mode—that is, like (format "~a" v)then concatenates the results with separator between consecutive items, and then pads or truncates the string to be at least min-width characters and at most max-width characters.

Examples:
> (~a "north")

"north"

> (~a 'south)

"south"

> (~a #"east")

"east"

> (~a #\w "e" 'st)

"west"

> (~a (list "red" 'green #"blue"))

"(red green blue)"

> (~a 17)

"17"

> (~a #e1e20)

"100000000000000000000"

> (~a pi)

"3.141592653589793"

> (~a (expt 6.1 87))

"2.1071509386211452e+68"

The ~a function is primarily useful for strings, numbers, and other atomic data. The ~v and ~s functions are better suited to compound data.

Let s be the concatenated string forms of the vs plus separators. If s is longer than max-width characters, it is truncated to exactly max-width characters. If s is shorter than min-width characters, it is padded to exactly min-width characters. Otherwise s is returned unchanged. If min-width is greater than max-width, an exception is raised.

If s is longer than max-width characters, it is truncated and the end of the string is replaced with limit-marker. If limit-marker is longer than max-width, an exception is raised. If limit-prefix? is #t, the beginning of the string is truncated instead of the end.

Examples:
> (~a "abcde" #:max-width 5)

"abcde"

> (~a "abcde" #:max-width 4)

"abcd"

> (~a "abcde" #:max-width 4 #:limit-marker "*")

"abc*"

> (~a "abcde" #:max-width 4 #:limit-marker "...")

"a..."

> (~a "The quick brown fox" #:max-width 15 #:limit-marker "")

"The quick brown"

> (~a "The quick brown fox" #:max-width 15 #:limit-marker "...")

"The quick br..."

> (~a "The quick brown fox" #:max-width 15 #:limit-marker "..." #:limit-prefix? #f)

"The quick br..."

If s is shorter than min-width, it is padded to at least min-width characters. If align is 'left, then only right padding is added; if align is 'right, then only left padding is added; and if align is 'center, then roughly equal amounts of left padding and right padding are added.

Padding is specified as a non-empty string. Left padding consists of left-pad-string repeated in its entirety as many times as possible followed by a prefix of left-pad-string to fill the remaining space. In contrast, right padding consists of a suffix of right-pad-string followed by a number of copies of right-pad-string in its entirety. Thus left padding starts with the start of left-pad-string and right padding ends with the end of right-pad-string.

Examples:
> (~a "apple" #:min-width 20 #:align 'left)

"apple               "

> (~a "pear" #:min-width 20 #:align 'left #:right-pad-string " .")

"pear . . . . . . . ."

> (~a "plum" #:min-width 20 #:align 'right #:left-pad-string ". ")

". . . . . . . . plum"

> (~a "orange" #:min-width 20 #:align 'center
                #:left-pad-string "- " #:right-pad-string " -")

"- - - -orange- - - -"

Use width to set both max-width and min-width simultaneously, ensuring that the resulting string is exactly width characters long:

> (~a "terse" #:width 6)

"terse "

> (~a "loquacious" #:width 6)

"loquac"

procedure

(~v v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string
Like ~a, but each value is converted like (format "~v" v), the default separator is " ", and the default limit marker is "...".

Examples:
> (~v "north")

"\"north\""

> (~v 'south)

"'south"

> (~v #"east")

"#\"east\""

> (~v #\w)

"#\\w"

> (~v (list "red" 'green #"blue"))

"'(\"red\" green #\"blue\")"

Use ~v to produce text that talks about Racket values.

Example:
> (let ([nums (for/list ([i 10]) i)])
    (~a "The even numbers in " (~v nums)
        " are " (~v (filter even? nums)) "."))

"The even numbers in '(0 1 2 3 4 5 6 7 8 9) are '(0 2 4 6 8)."

procedure

(~s v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string
Like ~a, but each value is converted like (format "~s" v), the default separator is " ", and the default limit marker is "...".

Examples:
> (~s "north")

"\"north\""

> (~s 'south)

"south"

> (~s #"east")

"#\"east\""

> (~s #\w)

"#\\w"

> (~s (list "red" 'green #"blue"))

"(\"red\" green #\"blue\")"

procedure

(~e v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string
Like ~a, but each value is converted like (format "~e" v), the default separator is " ", and the default limit marker is "...".

Examples:
> (~e "north")

"\"north\""

> (~e 'south)

"'south"

> (~e #"east")

"#\"east\""

> (~e #\w)

"#\\w"

> (~e (list "red" 'green #"blue"))

"'(\"red\" green #\"blue\")"

procedure

(~r x    
  [#:sign sign    
  #:base base    
  #:precision precision    
  #:notation notation    
  #:format-exponent format-exponent    
  #:min-width min-width    
  #:pad-string pad-string    
  #:groups groups    
  #:group-sep group-sep    
  #:decimal-sep decimal-sep])  string?
  x : rational?
  sign : 
(or/c #f '+ '++ 'parens
      (let ([ind (or/c string? (list/c string? string?))])
        (list/c ind ind ind)))
   = #f
  base : (or/c (integer-in 2 36) (list/c 'up (integer-in 2 36)))
   = 10
  precision : 
(or/c exact-nonnegative-integer?
      (list/c '= exact-nonnegative-integer?))
 = 6
  notation : 
(or/c 'positional 'exponential
      (-> rational? (or/c 'positional 'exponential)))
   = 'positional
  format-exponent : (or/c #f string? (-> exact-integer? string?))
   = #f
  min-width : exact-positive-integer? = 1
  pad-string : non-empty-string? = " "
  groups : (non-empty-listof exact-positive-integer?) = '(3)
  group-sep : string? = ""
  decimal-sep : string? = "."
Converts the rational number x to a string in either positional or exponential notation, depending on notation. The exactness or inexactness of x does not affect its formatting.

The optional arguments control number formatting:

  • notation determines whether the number is printed in positional or exponential notation. If notation is a function, it is applied to x to get the notation to be used.

    Examples:
    > (~r 12345)

    "12345"

    > (~r 12345 #:notation 'exponential)

    "1.2345e+04"

    > (let ([pick-notation
             (lambda (x)
               (if (or (< (abs x) 0.001) (> (abs x) 1000))
                   'exponential
                   'positional))])
        (for/list ([i (in-range 1 5)])
          (~r (expt 17 i) #:notation pick-notation)))

    '("17" "289" "4.913e+03" "8.3521e+04")

  • precision controls the number of digits after the decimal point (or more accurately, the radix point). When x is formatted in exponential form, precision applies to the significand.

    If precision is a natural number, then up to precision digits are displayed, but trailing zeroes are dropped, and if all digits after the decimal point are dropped the decimal point is also dropped. If precision is (list '= digits), then exactly digits digits after the decimal point are used, and the decimal point is never dropped.

    Examples:
    > (~r pi)

    "3.141593"

    > (~r pi #:precision 4)

    "3.1416"

    > (~r pi #:precision 0)

    "3"

    > (~r 1.5 #:precision 4)

    "1.5"

    > (~r 1.5 #:precision '(= 4))

    "1.5000"

    > (~r 50 #:precision 2)

    "50"

    > (~r 50 #:precision '(= 2))

    "50.00"

    > (~r 50 #:precision '(= 0))

    "50."

  • decimal-sep specifies what decimal separator is printed.

    Examples:
    > (~r 123.456)

    "123.456"

    > (~r 123.456 #:decimal-sep ",")

    "123,456"

  • groups controls how digits of the integral part of the number are separated into groups. Rightmost numbers of groups are used to group rightmost digits of the integral part. The leftmost number of groups is used repeatedly to group leftmost digits. The group-sep argument specifies which separator to use between digit groups.

    Examples:
    > (~r 1234567890 #:groups '(3) #:group-sep ",")

    "1,234,567,890"

    > (~r 1234567890 #:groups '(3 2) #:group-sep ",")

    "12,345,678,90"

    > (~r 1234567890 #:groups '(1 3 2) #:group-sep "_")

    "1_2_3_4_5_678_90"

  • min-width if x would normally be printed with fewer than min-width digits (including the decimal point but not including the sign indicator), the digits are left-padded using pad-string.

    Examples:
    > (~r 17)

    "17"

    > (~r 17 #:min-width 4)

    "  17"

    > (~r -42 #:min-width 4)

    "-  42"

    > (~r 1.5 #:min-width 4)

    " 1.5"

    > (~r 1.5 #:precision 4 #:min-width 10)

    "       1.5"

    > (~r 1.5 #:precision '(= 4) #:min-width 10)

    "    1.5000"

    > (~r #e1e10 #:min-width 6)

    "10000000000"

  • pad-string specifies the string used to pad the number to at least min-width characters (not including the sign indicator). The padding is placed between the sign and the normal digits of x.

    Examples:
    > (~r 17 #:min-width 4 #:pad-string "0")

    "0017"

    > (~r -42 #:min-width 4 #:pad-string "0")

    "-0042"

  • sign controls how the sign of the number is indicated:
    • If sign is #f (the default), no sign output is generated if x is either positive or zero, and a minus sign is prefixed if x is negative.

      Example:
      > (for/list ([x '(17 0 -42)]) (~r x))

      '("17" "0" "-42")

    • If sign is '+, no sign output is generated if x is zero, a plus sign is prefixed if x is positive, and a minus sign is prefixed if x is negative.

      Example:
      > (for/list ([x '(17 0 -42)]) (~r x #:sign '+))

      '("+17" "0" "-42")

    • If sign is '++, a plus sign is prefixed if x is zero or positive, and a minus sign is prefixed if x is negative.

      Example:
      > (for/list ([x '(17 0 -42)]) (~r x #:sign '++))

      '("+17" "+0" "-42")

    • If sign is 'parens, no sign output is generated if x is zero or positive, and the number is enclosed in parentheses if x is negative.

      Example:
      > (for/list ([x '(17 0 -42)]) (~r x #:sign 'parens))

      '("17" "0" "(42)")

    • If sign is (list pos-ind zero-ind neg-ind), then pos-ind, zero-ind, and neg-ind are used to indicate positive, zero, and negative numbers, respectively. Each indicator is either a string to be used as a prefix or a list containing two strings: a prefix and a suffix.

      Example:
      > (let ([sign-table '(("" " up") "an even " ("" " down"))])
          (for/list ([x '(17 0 -42)]) (~r x #:sign sign-table)))

      '("17 up" "an even 0" "42 down")

      The default behavior is equivalent to '("" "" "-"); the 'parens mode is equivalent to '("" "" ("(" ")")).

  • base controls the base that x is formatted in. If base is a number greater than 10, then lower-case letters are used. If base is (list 'up base*) and base* is greater than 10, then upper-case letters are used.

    Examples:
    > (~r 100 #:base 7)

    "202"

    > (~r 4.5 #:base 2)

    "100.1"

    > (~r 3735928559 #:base 16)

    "deadbeef"

    > (~r 3735928559 #:base '(up 16))

    "DEADBEEF"

    > (~r 3735928559 #:base '(up 16) #:notation 'exponential)

    "D.EADBEF*16^+07"

  • format-exponent determines how the exponent is displayed.

    If format-exponent is a string, the exponent is displayed with an explicit sign (as with a sign of '++) and at least two digits, separated from the significand by the “exponent marker” format-exponent:

    > (~r 1234 #:notation 'exponential #:format-exponent "E")

    "1.234E+03"

    If format-exponent is #f, the “exponent marker” is "e" if base is 10 and a string involving base otherwise:

    > (~r 1234 #:notation 'exponential)

    "1.234e+03"

    > (~r 1234 #:notation 'exponential #:base 8)

    "2.322*8^+03"

    If format-exponent is a procedure, it is applied to the exponent and the resulting string is appended to the significand:

    > (~r 1234 #:notation 'exponential
               #:format-exponent (lambda (e) (format "E~a" e)))

    "1.234E3"

Changed in version 8.5.0.5 of package base: Added #:groups, #:group-sep and #:decimal-sep.

procedure

(~.a v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = ""
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = ""
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string

procedure

(~.v v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string

procedure

(~.s v    
  ...    
  [#:separator separator    
  #:width width    
  #:max-width max-width    
  #:min-width min-width    
  #:limit-marker limit-marker    
  #:limit-prefix? limit-prefix?    
  #:align align    
  #:pad-string pad-string    
  #:left-pad-string left-pad-string    
  #:right-pad-string right-pad-string])  string?
  v : any/c
  separator : string? = " "
  width : (or/c exact-nonnegative-integer? #f) = #f
  max-width : (or/c exact-nonnegative-integer? +inf.0)
   = (or width +inf.0)
  min-width : exact-nonnegative-integer? = (or width 0)
  limit-marker : string? = "..."
  limit-prefix? : boolean? = #f
  align : (or/c 'left 'center 'right) = 'left
  pad-string : non-empty-string? = " "
  left-pad-string : non-empty-string? = pad-string
  right-pad-string : non-empty-string? = pad-string
Like ~a, ~v, and ~s, but each v is formatted like (format "~.a" v), (format "~.v" v), and (format "~.s" v), respectively.