Function: regexp-opt-charset

regexp-opt-charset is a byte-compiled function defined in regexp-opt.el.gz.

Signature

(regexp-opt-charset CHARS)

Documentation

Return a regexp to match a character in CHARS.

CHARS should be a list of characters. If CHARS is the empty list, the return value is a regexp that never matches anything.

Other relevant functions are documented in the regexp group.

View in manual

Shortdoc

;; regexp
(regexp-opt-charset '(97 98 99 100 101))
    => "[a-e]"

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/regexp-opt.el.gz
(defun regexp-opt-charset (chars)
  "Return a regexp to match a character in CHARS.
CHARS should be a list of characters.
If CHARS is the empty list, the return value is a regexp that
never matches anything."
  (declare (pure t) (side-effect-free t))
  ;; The basic idea is to find character ranges.  Also we take care in the
  ;; position of character set meta characters in the character set regexp.
  ;;
  (let* ((charmap (make-char-table 'regexp-opt-charset))
	 (start -1) (end -2)
	 (charset "")
	 (bracket "") (dash "") (caret ""))
    ;;
    ;; Make a character map but extract character set meta characters.
    (dolist (char chars)
      (cond
       ((eq char ?\])
	(setq bracket "]"))
       ((eq char ?^)
	(setq caret "^"))
       ((eq char ?-)
	(setq dash "-"))
       (t
	(aset charmap char t))))
    ;;
    ;; Make a character set from the map using ranges where applicable.
    (map-char-table
     (lambda (c v)
       (when v
	 (if (consp c)
	     (if (= (1- (car c)) end) (setq end (cdr c))
	       (if (> end (+ start 2))
		   (setq charset (format "%s%c-%c" charset start end))
		 (while (>= end start)
		   (setq charset (format "%s%c" charset start))
		   (setq start (1+ start))))
	       (setq start (car c) end (cdr c)))
	   (if (= (1- c) end) (setq end c)
	     (if (> end (+ start 2))
	       (setq charset (format "%s%c-%c" charset start end))
	     (while (>= end start)
	       (setq charset (format "%s%c" charset start))
	       (setq start (1+ start))))
	     (setq start c end c)))))
     charmap)
    (when (>= end start)
      (if (> end (+ start 2))
	  (setq charset (format "%s%c-%c" charset start end))
	(while (>= end start)
	  (setq charset (format "%s%c" charset start))
	  (setq start (1+ start)))))

    ;; Make sure that ] is first, ^ is not first, - is first or last.
    (let ((all (concat bracket charset caret dash)))
      (pcase (length all)
        (0 regexp-unmatchable)
        (1 (regexp-quote all))
        (_ (if (string-equal all "^-")
               "[-^]"
             (concat "[" all "]")))))))