For the sake of alternatives, first of all, since you are looking to test against a number of different characters, it looks like a regular expression would do the job more succinctly and, perhaps even faster (really depends on how many characters there will be to test from etc.)
Another way is to use char-table
- a built-in Emacs data-structure for working with characters. Below is an example followed by explanation:
(defun char-handler () (message "I am char-handler"))
(defun special-handler () (message "I am special-handler"))
(defvar test-char-table (make-char-table 'testing 'char-handler))
(set-char-table-range test-char-table ?a 'special-handler)
(funcall (char-table-range test-char-table '?a))
"I am special-handler"
(funcall (char-table-range test-char-table '?b))
"I am char-handler"
make-char-table
creates a sparse array-like structure where keys are characters and the values are whatever you want, but usually symbols pointing to some function. This data-structure is specifically designed to handle text processing so it should be reasonably fast, but, most importantly, it scales better with more handlers. It's dynamic (which means that adding or removing handlers is possible while without changing the rest of the code which uses relies on the function using it.
When you call set-char-table-range
you can also provide things other than single character: ranges of characters given by cons cell with car
being the first character of the range and cdr
being the last character. This helps when you have many characters which have to invoke the same handler. It also accepts nil
meaning "all characters in the table".
For more info, such as functions which inspect the table and iterate over its contents see: https://www.gnu.org/software/emacs/manual/html_node/elisp/Char_002dTables.html#Char_002dTables