[Top][All Lists]
[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