0

I would like to know a function that searches a pattern located before point.

re-search-backward is mentioned in the Elisp manual but I do not understand its purpose. Indeed, I do not understand the explanation given in the manual nor some of the cases found.

re-search-backward regexp &optional limit noerror count

This function searches backward in the current buffer for a string of text that is matched by the regular expression regexp, leaving point at the beginning of the first text found.

This function is analogous to re-search-forward, but they are not simple mirror images. re-search-forward finds the match whose beginning is as close as possible to the starting point. re-search-forward finds the match whose beginning is as close as possible to the starting point. If re-search-backward were a perfect mirror image, it would find the match whose end is as close as possible. However, in fact it finds the match whose beginning is as close as possible (and yet ends before the starting point). The reason for this is that matching a regular expression at a given spot always works from beginning to end, and starts at a specified beginning position.

I did a search but found only unsatisfactory answers.

  1. emacs greedy search-backward-regexp
  2. Why is the order of : and - important in a regexp character class

These threads suggest that there is no standard solution. The use of skip-chars-backward seems to me particularly unsuitable because it is used for the internal workings of Emacs (see syntax.c).

Suppose the current buffer contains only a string of text composed of alphabetic characters (e.g. abc), anywhere before the point. In this case, (re-search-backward "[[:alpha:]]+") moves the point between the last two characters (between b and c) when the position is expected to be at the beginning of the text (before a).

  • 3
    Question needs clarification on the specifics of what doesn't work, what you're expecting and why re-search-backwards doesn't fit your case. I cannot discern what's the problem, if we're talking about greediness backwards, if you want to search forward from the beginning of buffer to point or something else. – Muihlinn Jun 1 at 10:42
  • 1
    @Fólkvangr, do you mean that the pattern should be immediately before the point or somewhere between the beginning of the buffer and the point? In the first case you cal use re-search-backward and use \= to match point, or looking-back. In the latter case, re-search-backward should work. – Lindydancer Jun 1 at 12:48
2

It gives you the first match it finds.

In your abc example, c is a match for [[:alpha:]]+, so it stops there. The actual regexp matching is always forwards; it's just the starting position which is moved backwards until a match is found. If you searched for "\\b[[:alpha:]]+" then abc would be the first match.

Note that what you are (IIUC) expecting would require not merely finding a successful match; but continuing to iteratively perform the pattern match from every earlier starting position in the buffer in turn (within the specified bounds), in order to discover the longest match -- potentially a very expensive operation. Note that you can't stop at the first non-matching position, because there might be positions before that which once again match through to the required end-point. Unless the pattern is anchored in some way which provides a guaranteed limit to how far back it could start, you can't know which of the potential start points will provide the longest match1 without checking all of them.

(In your example, we can of course see that any non-alpha character imposes a guaranteed limit for matching the regexp [[:alpha:]]+; but that is a very trivial case, whereas any such behaviour in Emacs would need to be generalised for regexps of arbitrary complexity.)

Searching forwards is usually better than searching backwards, if you can make it work. If you know the bounds of the searchable text (and you generally want to have those regardless), then a forwards search from that start point may be easier to reason about.


1 Not that the normal regexp searches guarantee the longest match in any case, which is why we have C-hig (elisp)POSIX Regexps -- but those also don't behave any differently with respect to the backwards-search start-point issue, and so using posix-search-backward doesn't change the outcome of your example at all.

| improve this answer | |

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.