Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create shy groups in Emacs with rx?

Tags:

emacs

elisp

Generally, I can use the excellent rx macro to create readable regular expressions and be sure that I've escaped the correct metacharacters.

(rx (any "A-Z")) ;; "[A-Z]"

However, I can't work out how to create shy groups, e.g. \(?:AB\). rx sometimes produces them in its output:

(rx (or "ab" "bc")) ;; "\\(?:ab\\|bc\\)"

but I want to explicitly add them. I can do:

(rx (regexp "\\(?:AB\\)"))

but this defeats the point of rx.

In a perfect world, I'd like to be able to write:

(rx (shy-group "A"))

I'd settle for something like this (none of these work):

;; sadly, `regexp` only accepts literal strings
(rx (regexp (format "\\(?:%s\\)" (rx WHATEVER))))

;; also unfortunate, `eval` quotes the string it's given
(rx (eval (format "\\(?:%s\\)" (rx WHATEVER))))

How can I create regular expressions with shy groups using rx?

like image 417
Wilfred Hughes Avatar asked Jun 13 '13 09:06

Wilfred Hughes


2 Answers

I think the structure of a rx form eliminates any need to explicitly create shy groups -- everything that a shy group could be needed for is accounted for by other syntax.

e.g. your own example:

(rx (or "ab" "bc")) ;; "\\(?:ab\\|bc\\)"
like image 54
phils Avatar answered Oct 01 '22 03:10

phils


For other cases, it is also possible to extend the keywords used by rx.

Example (taken from EmacsWiki link above):

(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)))
like image 44
gsl Avatar answered Oct 01 '22 05:10

gsl