Skip to main content

upper-case-p, lower-case-p, both-case-p

upper-case-p, lower-case-p, both-case-p Function

Syntax:

upper-case-p character → generalized-boolean

lower-case-p character → generalized-boolean

both-case-p character → generalized-boolean

Arguments and Values:

character—a character .

generalized-boolean—a generalized boolean.

Description:

These functions test the case of a given character.

upper-case-p returns true if character is an uppercase character ; otherwise, returns false. lower-case-p returns true if character is a lowercase character ; otherwise, returns false. both-case-p returns true if character is a character with case; otherwise, returns false.

Examples:

(upper-case-p #\A) → true 
(upper-case-p #\a) → false
(both-case-p #\a) → true
(both-case-p #\5) → false
(lower-case-p #\5) → false
(upper-case-p #\5) → false
;; This next example presupposes an implementation
;; in which #\Bell is an implementation-defined character.
(lower-case-p #\Bell) → false


Exceptional Situations:

Should signal an error of type type-error if character is not a character .

See Also:

char-upcase, char-downcase, Section 13.1.4.3 (Characters With Case), Section 13.1.10 (Documentation of Implementation-Defined Scripts)

Expanded Reference: upper-case-p, lower-case-p, both-case-p

Testing for uppercase letters

upper-case-p returns true if the character is an uppercase letter.

(upper-case-p #\A)
=> T
(upper-case-p #\Z)
=> T
(upper-case-p #\a)
=> NIL
(upper-case-p #\5)
=> NIL

Testing for lowercase letters

lower-case-p returns true if the character is a lowercase letter.

(lower-case-p #\a)
=> T
(lower-case-p #\z)
=> T
(lower-case-p #\A)
=> NIL
(lower-case-p #\5)
=> NIL

Testing whether a character has case

both-case-p returns true if the character has both an uppercase and a lowercase variant -- that is, it is a letter with case.

(both-case-p #\a)
=> T
(both-case-p #\A)
=> T
(both-case-p #\5)
=> NIL
(both-case-p #\Space)
=> NIL
(both-case-p #\+)
=> NIL

Relationship between the three predicates

For any character, both-case-p is true if and only if either upper-case-p or lower-case-p is true.

(defun verify-case-consistency (char)
(eql (both-case-p char)
(or (upper-case-p char) (lower-case-p char))))

(every #'verify-case-consistency
(coerce "ABCabc012!@#" 'list))
=> T

Practical use: counting case statistics in a string

(defun case-stats (string)
(list :upper (count-if #'upper-case-p string)
:lower (count-if #'lower-case-p string)
:no-case (count-if-not #'both-case-p string)))

(case-stats "Hello, World!")
=> (:UPPER 2 :LOWER 8 :NO-CASE 3)

Filtering by case

(remove-if-not #'upper-case-p "Hello World")
=> "HW"

(remove-if-not #'lower-case-p "Hello World")
=> "elloorld"