1

Here is my expression:

(setq myregexp (rx bol
                   "####"
                   (one-or-more anything)
                   "."))

This should match any string starting with "####", spanning over zero or mode new lines, and stop at the first found "." right?

This is my test buffer:

#### This.
#### This too.
#### And also
this.
#### Oh, and this too.
But not this.

And here is the fn that I use to test it:

(defun regtest ()
  "search"
  (interactive)
  (save-excursion
    (while
        (re-search-forward myregexp nil t nil)
      (message "Found [%s] and [%s]" (match-string 0) (match-string 1)))))

But here is what it returns:

Found [#### This.
#### This too.
#### And also
this.
#### Oh, and this too.] and [nil]

How can I make the regexp stop at the first found match of the last rx expression? And more generally, how to properly use anything?

  • 1
    In general when I use regular expressions, if I want to match everything up to the first ".", I replace "anything" by "[^.]". With rx, have you tried "minimal-match"? – John Palmieri Aug 23 '17 at 15:25
  • @JohnPalmieri minimal-match worked ; you should make it an answer so I can accept it ; it's a big deal, I mean, that was my last gripe about rx.el and I think everybody wants to know about this one, you do realize there is no rx.el documentation apart from the very lib header? :) Thanks! – yPhil Aug 23 '17 at 15:35
  • Her is the expression that worked, you can use it in your answer: ` (setq myregexp-interactive (rx bol "####" (minimal-match (and (one-or-more anything) ".")) )) ` – yPhil Aug 23 '17 at 15:38
  • Regarding the documentation: Have you checked C-h f rx? – Erik Aug 26 '17 at 17:05
2

In general when I use regular expressions, if I want to match everything up to the first ".", I replace anything by "[^.]". With rx, if you want to use anything, I suggest using minimal-match. This apparently succeeds (worked out by @yPhil):

(setq myregexp-interactive (rx bol 
                               "####" 
                               (minimal-match (and (one-or-more anything) ".")) ))

Note that I discovered minimal-match by reading the source code, not because of any documentation for rx.

  • 1
    minimal-match is also in the rx docstring. Other possibly relevant things in the docstring: rx-greedy-flag and +? which is described as "like one-or-more, but always produces a non-greedy regexp." – npostavs Aug 23 '17 at 16:20
  • 1
    Good to know. I think in a perfect world, rx would be covered in the Elisp info page. I couldn't find it there. – John Palmieri Aug 23 '17 at 17:15
  • The rx equivalent for [^.] is (not (any ".")), so the whole regex would be (rx bol "####" (one-or-more (not (any "."))) "."). – Erik Aug 26 '17 at 17:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.