String, Character, and Bytevector Procedures

Convert letter case, compare characters, read string positions, and access bytes from 0 through 255.

Use these procedures to convert text, compare characters, and read individual bytes. The examples show which case conversions change string length and which characters count as digits.

Convert text and read a byte

Run this complete example in the Playground.

LISPEX
(list (string-upcase "Lispex") (char-numeric? #\7) (bytevector-u8-ref #u8(65) 0))

Result

OUTPUT
("LISPEX" #t 65)

The first call converts a string to uppercase. The second checks whether the character #\7 is a digit. The third reads the first byte of #u8(65). Positions start at 0.

Distinguish string and character conversions

LISPEX
(list (string-upcase "Straße")
      (char-upcase #\ß)
      (char-ci=? #\A #\a)
      (char-ci=? #\ς #\σ)
      (string-ci=? "Straße" "STRASSE"))

Result

OUTPUT
("STRASSE" #\ß #t #f #f)

String case conversion uses Unicode mappings and can change length. Here, string-upcase converts ß to SS. Character case conversion returns one character, so char-upcase leaves #\ß unchanged.

The ci in char-ci=? and string-ci=? means “case-insensitive.” These procedures compare after converting to lowercase. They treat ASCII letters A through Z like a through z, so the third result is #t.

Some Unicode characters need more than lowercasing to match. Greek final sigma ς and sigma σ remain different here, as do "Straße" and "STRASSE". Those comparisons return #f.

The char-foldcase and string-foldcase procedures perform the same lowercase conversions used by these comparisons. This is an approximation of Unicode case folding, the conversion used to compare text without letter case.

Count characters and recognize digits

A character such as #\A or #\한 is one Unicode scalar value. A string is a sequence of these characters. String positions count characters, not UTF-8 bytes.

CallResultMeaning
(string-ref "한A" 0)#\한The first character
(string-length "한A")2Two characters
(char-numeric? #\7)#fThe fullwidth digit is not an ASCII digit
(char-alphabetic? #\한)#tAlphabetic classification uses Unicode

The char-numeric? procedure recognizes only #\0 through #\9. Alphabetic, whitespace, uppercase, and lowercase predicates use Unicode properties. Character comparisons use Unicode scalar order.

Check arguments and results

You can create, copy, append, compare, and map strings, or convert them to and from lists and vectors. Strings and bytevectors are immutable. Operations that produce new strings leave the input unchanged.

CallResultInput rules
(string-ref string k)One characterk is an exact integer from 0 through length minus one; E312 for a wrong type, E311 out of range
(string-append string ...)A new stringEach argument is a string
(char-ci=? char char ...)A booleanCompare two or more characters after the conversion described above
(string-map proc string)A new stringOne string; calls proc from left to right; each call must return exactly one character
(bytevector-u8-ref bytes k)An exact integer from 0 through 255k is an exact integer from 0 through length minus one; E312 for a wrong type, E311 out of range

Use bytevector-length to find the number of bytes before indexing. Bytevector elements range from 0 through 255.

This version provides string and bytevector reading. String mutation, bytevector mutation, bytevector copying or appending, and UTF-8 encoding or decoding procedures are not available.

Data and aggregate types introduces these values. The procedure index lists the other procedure families.