Nyquist / XLISP 2.0  -  Contents | Tutorials | Examples | Reference

POSIX Character Classes


  1. POSIX Character Classes
  2. Internal Functions
  3. User Functions

POSIX Character Classes


The functions on this page implement tests for the standard POSIX character classes, where all functions return the tested character if the test succeeds, or NIL if the test fails.

The built-in XLISP character test functions upper-case-p, lower-case-p, both-case-p, alphanumericp, return the boolean values  T  or NIL instead of the tested character, while digit-char-p returns an integer or NIL, what is handy if you want to convert arbitrary Lisp symbols into numbers without producing an error, but all this is impractical for writing a string parser.

The Internal Functions do not check if the argument is a character and therefore are faster than the User Functions. Also note that XLISP is limited to ASCII characters, so there is no way to find out if an unicode character is upper- or lowercase if the character code is greater than ASCII 127.

   POSIX   -   Internal   -   User Function
   [: alnum :]   -   char:alnum-p   -   alnum-character-p   -  alphanumeric = [a-z], [A-Z], [0-9]
   [: alpha :]   -   char:alpha-p   -   alpha-character-p   -  alphabetic = [a-z], [A-Z]
   [: blank :]   -   char:blank-p   -   blank-character-p   -  space and horizontal-tab
   [: cntrl :]   -   char:cntrl-p   -   cntrl-character-p   -  code-chars 0-31 and 127
   [: digit :]   -   char:digit-p   -   digit-character-p   -  decimal = [0-9]
   [: graph :]   -   char:graph-p   -   graph-character-p   -  graphical = alnum + punct
   [: lower :]   -   char:lower-p   -   lower-character-p   -  lowercase = [a-z]
   [: print :]   -   char:print-p   -   print-character-p   -  printable = alnum + punct + space
   [: punct :]   -   char:punct-p   -   punct-character-p   -  punctuation marks
   [: space :]   -   char:space-p   -   space-character-p   -  characters producing whitespace
   [: upper :]   -   char:upper-p   -   upper-character-p   -  uppercase = [A-Z]
   [: xdigit :]   -   char:xdigit-p   -   xdigit-character-p   -  hexadecimal = [0-9], [a-f], [A-F]

The main difference is:

> (char:alnum-p 'nonsense-value)
error: bad argument type - NONSENSE-VALUE

> (alnum-character-p 'nonsense-value)
NIL

  Back to top


Internal Functions


The internal functions are based on built-in XLISP functions, there are no external dependencies.

;; alphanumeric characters = a-z, A-z, 0-9

(defun char:alnum-p (char)
  (and (alphanumericp char)
       char))

;; alphabetic characters = a-z, A-Z

(defun char:alpha-p (char)
  (and (both-char-p char)
       char))

;; blanks = space and horizontal-tab

(defun char:blank-p (char)
  (and (or (char= char #\Space)
           (char= char #\Tab))
       char))

;; control characters = code-chars 0-31 and 127

(defun char:cntrl-p (char)
  (let ((code (char-code char)))
    (and (or (<= 0 code 31)
             (= code 127))
         char)))

;; decimal digits = 0-9

(defun char:digit-p (char)
  (and (digit-char-p char)
       char))

;; graphical characters = alnum + punct

(defun char:graph-p (char)
  (and (<= 33 (char-code char) 126)
       char))

;; lowercase characters = a-z

(defun char:lower-p (char)
  (and (lower-case-p char)
       char))

;; printable characters = alnum + punct + space

(defun char:print-p (char)
  (and (<= 32 (char-code char) 126)
       char))

;; punctuation marks

(defun char:punct-p (char)
  (let ((code (char-code char)))
    (and (or (<=  33 code  47)   ;  ! " # $ % & ' ( ) * + , - . /
             (<=  58 code  64)   ;  : ; < = > ? @
             (<=  91 code  96)   ;  [ \ ] ^ _ `
             (<= 123 code 126))  ;  { | } ~
         char)))

;; characters producing whitespace
;;
;;  9 = horizontal tab   10 = line feed         11 = vertical tab
;; 12 = form feed        13 = carriage return   32 = space

(defun char:space-p (char)
  (and (member (char-code char) '(9 10 11 12 13 32))
       char))

;; uppercase characters = A-Z

(defun char:upper-p (char)
  (and (upper-case-p char)
       char))

;; hexadecimal digits = 0-9, a-f, A-F

(defun char:xdigit-p (char)
  (and (or (digit-char-p char)
           (let ((code (char-code char)))
             (or (<= 65 code  70)     ; A-Z
                 (<= 97 code 102))))  ; a-z
       char))

  Back to top


User Functions


The user functions are based on the Internal Functions above. There are no other dependencies.

;; alphanumeric characters = a-z, A-z, 0-9

(defun alnum-character-p (char)
  (and (characterp char)
       (char:alnum-p char)))

;; alphabetic characters = a-z, A-Z

(defun alpha-character-p (char)
  (and (characterp char)
       (char:alpha-p char)))

;; blanks = space and horizontal-tab

(defun blank-character-p (char)
  (and (characterp char)
       (char:blank-p char)))

;; control characters = code-chars 0-31 and 127

(defun cntrl-character-p (char)
  (and (characterp char)
       (char:cntrl-p char)))

;; decimal digits = 0-9

(defun digit-character-p (char)
  (and (characterp char)
       (char:digit-p char)))

;; graphical characters = alnum + punct

(defun graph-character-p (char)
  (and (characterp char)
       (char:graph-p char)))

;; lowercase characters = a-z

(defun lower-character-p (char)
  (and (characterp char)
       (char:lower-p char)))

;; printable characters = alnum + punct + space

(defun print-character-p (char)
  (and (characterp char)
       (char:print-p char)))

;; punctuation marks

(defun punct-character-p (char)
  (and (characterp char)
       (char:punct-p char)))

;; characters producing whitespace

(defun space-character-p (char)
  (and (characterp char)
       (char:space-p char)))

;; uppercase characters = A-Z

(defun upper-character-p (char)
  (and (characterp char)
       (char:upper-p char)))

;; hexadecimal digits = 0-9, a-f, A-F

(defun xdigit-character-p (char)
  (and (characterp char)
       (char:xdigit-p char)))

  Back to top


Nyquist / XLISP 2.0  -  Contents | Tutorials | Examples | Reference