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?

4
  • 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"? Aug 23, 2017 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, 2017 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, 2017 at 15:38
  • Regarding the documentation: Have you checked C-h f rx?
    – Nova
    Aug 26, 2017 at 17:05

1 Answer 1

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.

3
  • 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, 2017 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. Aug 23, 2017 at 17:15
  • The rx equivalent for [^.] is (not (any ".")), so the whole regex would be (rx bol "####" (one-or-more (not (any "."))) ".").
    – Nova
    Aug 26, 2017 at 17:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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