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

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

Re: looking-back


From: Tom Wurgler
Subject: Re: looking-back
Date: Tue, 17 Jun 2003 16:44:36 -0400 (EDT)


Recently "Stefan Monnier" <monnier+gnu/emacs/address@hidden> wrote:

Monnier> What is looking-back meant for ?

I use it in an elisp code I wrote to check on a given string (in this case) at
the end of a line.  It was easier to do (end-of-line) (if (looking-back "SI")...
than any other way.

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

Monnier> (if foo t nil) can be simplified to `foo', the problem is that

Huh?

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

Monnier> returns nil.  

For me, I wouldn't put an or in this because one wouldn't know which match it
matched. I make a decision in my code depending on what it is.  Which doesn't
help because it says REGEXP and therefore should work, I guess.  I don't know
how to do it differently unless you write a splitter to search each "or" piece
one at a time.

Monnier> Another problem is that by warning that match-data
Monnier> will be modified, it implicitly says that other functions that don't
Monnier> mention it probably preserve the match-data, whereas the rule is
Monnier> rather that the match-data is usually not preserved, and especially
Monnier> so for functions taking regexps as arguments.

I just scarfed the docs for looking-at.  I have no problem leaving that doc off.

Monnier> Finally, `looking-at' is very fast because it just does a regexp-match.
Monnier> On the other hand `looking-back' is a regexp *search* which tends to be
Monnier> orders of magnitude slower and it will typically search all the way
Monnier> to point-min when the search fails, so we want to add a `limit'
Monnier> argument, as is done for re-search-backward.

I guess I don't see a need to compare speeds to looking-at.  Of course, that is
built-in code and this isn't.  99% of the time this is lighting fast too.

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

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

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

Well, this seems to work for the hello\\|l case, but see above.

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

I gotta think about this some more.  How to stop it sooner if it doesn't match.

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

Well, this original method works pretty swell most all the time...

thanks
tom





reply via email to

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