A nifty macro that generates regular expressions for you, from reasonably-comprehensible s-expressions. Inspired by something similar in Olin Shivers’ “scsh”. Use decribe-function
found by pressing C-h f then enter rx
to find the full documentation with all usable keywords.
Example:
(rx bol
(zero-or-more blank)
(one-or-more digit)
":")
yields
""^[[:blank:]]*[[:digit:]]+:""
When given just a single string argument, it acts just like regexp-to-string.
Here is one way in which to temporarily extend the keywords used by rx for specific purposes:
(defmacro rx-extra (&rest body-forms) (let ((add-ins (list `(file . ,(rx (+ (or alnum digit "." "/" "-" "_")))) `(ws0 . ,(rx (0+ (any " " "\t")))) `(ws+ . ,(rx (+ (any " " "\t")))) `(int . ,(rx (+ digit)))))) `(let ((rx-constituents (append ',add-ins rx-constituents nil))) ,@body-forms)))
For the newer version, use:
(defmacro rx-extra (&rest body-forms) `(rx-let ((file (+ (or alnum digit "." "/" "-" "_"))) (ws0 (0+ (any " " "\t"))) (ws+ (+ (any " " "\t"))) (int (+ digit))) ,@body-forms))
Example of using the above rx-extra macro:
(let ((string " at Isrc/file-23_2.c line 23 ;: flubber")) (if (string-match (rx-extra (rx ws+ "at" ws+ (group file) ws+ "line" ws+ (group int))) string) (format "file is %s line is %s" (match-string-no-properties 1 string) (match-string-no-properties 2 string))))
This returns: “file is Isrc/file-23_2.c line is 23”
So the idea behind rx-extra is that you can add new named regular expressions to be used cleanly in other rx forms.