I would like to write a package that uses user defined regular expressions.
Is there a way to validate a regular expression is valid without having to perform a search, showing a helpful message when it's not?
Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. It only takes a minute to sign up.
Sign up to join this communityIf you want to check it interactively:
(defcustom foo "" "foo" :type 'regexp :group 'emacs)
Try giving it an invalid regexp and setting it, and it will raise an error.
Or if you want to test it programmatically, this predicate returns t
for valid and nil
for invalid, and when invalid it shows a message with the error type.
(defun regexp-valid-p (string)
"Return nil if STRING is not a valid regexp."
(condition-case err
(prog1 t (string-match-p string ""))
(error (message (error-message-string err))
nil)))
This works because string-match-p
and string-match
return either nil
or non-nil
for any valid regexp, and they raise an error for an invalid regexp. The condition-case
just captures the error, converts its message to an ordinary message
instead, and returns nil
for invalid and t
for valid.
This solution comes almost directly from the definition of function widget-regexp-match
(or function widget-regexp-validate
) in standard library wid-edit.el
.
In other words, I started from knowing that Customize checks validity of a field of :type regexp
, and looked for the code that checked that.
Another programmatic solution, also found by looking in the Elisp source code:
use function mh-index-parse-search-regexp
, defined in standard library mh-search.el
.
Example:
(mh-index-parse-search-regexp "\\(ab") ;; Raises an invalid-regexp error.
That function depends on these functions being defined:
mh-replace-string
; Defined in mh-utils.el
.mh-index-add-implicit-ops
; Defined in mh-search.el
.mh-index-evaluate
; Defined in mh-search.el
.Moral: If what you want to do seems like something that would be useful generally, there's a good chance it's already been done, and a good place to start looking is the source Lisp code provided with Emacs.
You can test a regular expression on a document with M-x re-builder
and build it interactively. Faulty parts are highlighted.