emacs-pretest-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

looking-back


From: Stefan Monnier
Subject: looking-back
Date: Tue, 17 Jun 2003 15:01:08 -0400

What is looking-back meant for ?

 (defun looking-back (regexp)
   "Return t if text before point matches regular expression REGEXP.
 This function modifies the match data that `match-beginning',
 `match-end' and `match-data' access; save and restore the match
 data if you want to preserve them."
   (save-excursion
     (let ((beg (point)))
       (if (re-search-backward regexp nil t)
          (if (= (match-end 0) beg)
              t
            nil)
        nil))))

Other than the minor fact that it's not mentioned in NEWS, and that
(if foo t nil) can be simplified to `foo', the problem is that

        (progn
          (insert "hello")
          (looking-back "hello\\|l"))

returns nil.  Another problem is that by warning that match-data
will be modified, it implicitly says that other functions that don't
mention it probably preserve the match-data, whereas the rule is
rather that the match-data is usually not preserved, and especially
so for functions taking regexps as arguments.
Finally, `looking-at' is very fast because it just does a regexp-match.
On the other hand `looking-back' is a regexp *search* which tends to be
orders of magnitude slower and it will typically search all the way
to point-min when the search fails, so we want to add a `limit'
argument, as is done for re-search-backward.

By the way, the only fix I know for the main problem is to do:

  (defun looking-back (regexp &optional limit)
    "Return non-nil if text before point matches REGEXP.
  Contrary to `looking-at', it will return the shortest match and it is
  typically orders of magnitude slower."
    (save-excursion
      (re-search-backward (concat "\\(?:" regexp "\\)\\=") limit t)))

This is also the only use I know of for the \= regexp operator.

Note that when Tom's original code works correctly, it will tend
to be faster because it will stop at the first unsuccessful match
whereas mine will always search all the way to `limit' before
returning nil.

The real answer is to write a regexp-engine that matches backward.


        Stefan





reply via email to

[Prev in Thread] Current Thread [Next in Thread]