[gnu.emacs.bug] replace-regexp

mlittman@WIND.BELLCORE.COM (Michael S. Littman) (12/02/88)

GNU Emacs 18.52.6 of Tue Sep  6 1988 on wind (berkeley-unix)

Why is it that calling replace-regexp from an Emacs program sets the
mark and prints "done"?  It seems to me that this is only necessary
when it is called interactively.  In fact, it really looks bad in the
program I'm writing and I don't know of any way to turn it off.

-Michael

loic%axis_d@axis.axis.fr (04/11/89)

Flame's hot line: 46 05 89 51


In GNU Emacs 18.52.10 of Sun Feb 19 1989 on axis_d (usg-unix-v)

(replace-regexp "^." "" ())

It empties my buffer !

I guess that it removes the character. Then the point is still
at the beginning of the line. So it removes the next one. And
so on.

It should skip to the next new-line. Don't you think so ?




			    Loic  Dachary
			     Axis Design
			 135 Rue d'Aguesseau
			92100 Boulogne, France
			  Tel : 46 05 89 51
			USENET : loic@axis.fr

merlyn@intelob.intel.com (Randal L. Schwartz @ Stonehenge) (04/11/89)

In article <8904102352.AA22601@inria.inria.fr>, loic%axis_d writes:
| In GNU Emacs 18.52.10 of Sun Feb 19 1989 on axis_d (usg-unix-v)
| 
| (replace-regexp "^." "" ())
| 
| It empties my buffer !
| 
| I guess that it removes the character. Then the point is still
| at the beginning of the line. So it removes the next one. And
| so on.

I recently battled this in 18.53 as well.  I was replacing
"^ " with "", and ended up deleting all initial spaces.

C'mon y'all... vi gets it right... :-)
-- 
/=====Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095========\
{        on contract to BiiN (for now :-) Hillsboro, Oregon, USA.             }
{<@intel-iwarp.arpa:merlyn@intelob.intel.com> ...!uunet!tektronix!biin!merlyn }
\=====Cute quote: "Welcome to Oregon... home of the California Raisins!"======/

gildea@BBN.COM (Stephen Gildea) (04/12/89)

    Date: Tue, 11 Apr 89 01:52:42 +0200
    From: loic%axis_d@axis.axis.fr
    To: axis!bug-gnu-emacs@prep.ai.mit.edu
    Subject: replace-regexp
    
    (replace-regexp "^." "" ())
    
    It empties my buffer !
    
    I guess that it removes the character. Then the point is still
    at the beginning of the line. So it removes the next one. And
    so on.
    
    It should skip to the next new-line. Don't you think so ?


No!  There is no reason for such special casing; you're just using the
wrong regexp.  Try (replace-regexp "^.\\(.*\\)$" "\\1").

 < Stephen

spencer@eecs.umich.edu (Spencer W. Thomas) (04/12/89)

In article <8904102352.AA22601@inria.inria.fr> loic%axis_d@axis.axis.fr writes:

>   (replace-regexp "^." "" ())
>
>   It empties my buffer !
> ...
>   It should skip to the next new-line. Don't you think so ?

Well, no.  Emacs is a character-oriented editor, NOT a line-oriented
editor.  Would you want it to skip to the next line after each
replacement if the strings were (say) "abc" and ""?  How should it
distinguish the two cases?  To get the effect (that I presume) you
want, you can say
	(replace-regexp "^.\\(.?\\)" "\\1")
or	(replace-regexp "^.\\(.*\\)" "\\1")

I think the first will be a little more efficient.

--
=Spencer (spencer@eecs.umich.edu)

israel@STARBASE.MITRE.ORG (Bruce Israel) (04/13/89)

   From: mailrus!sharkey!itivax!umich!zip!spencer@purdue.edu  (Spencer W. Thomas)

   In some article loic%axis_d@axis.axis.fr writes:

   >   (replace-regexp "^." "" ())
   >   It empties my buffer !
   >   It should skip to the next new-line. Don't you think so ?

   Well, no.  Emacs is a character-oriented editor, NOT a line-oriented
   editor.  Would you want it to skip to the next line after each
   replacement if the strings were (say) "abc" and ""?  

No, it shouldn't skip to the next line, but it SHOULD skip past the
previously matched string.  i.e. replacing "foo bar" with "foo" should not
change "foo bar bar " to "foo", it should become "foo bar".  A replacement
should not be re-run on the results of the replacement.  Effectively, a
replace-<whatever> should look like it found all non-overlapping occurences
of the search item first, and then did the change second.  For a similar 
example, should the null op (replace-string "a" "a") be an infinite loop?

I think that the workarounds given for this problem are excessively
complicated for the task the guy is trying to perform.

Bruce

jr@bbn.com (John Robinson) (04/14/89)

In article <8904130343.AA05725@starbase>, israel@STARBASE (Bruce Israel) writes:
>
>   From: mailrus!sharkey!itivax!umich!zip!spencer@purdue.edu  (Spencer W. Thomas)
>
>   In some article loic%axis_d@axis.axis.fr writes:
>
>   >   (replace-regexp "^." "" ())
>   >   It empties my buffer !
>   >   It should skip to the next new-line. Don't you think so ?
>
>   Well, no.  Emacs is a character-oriented editor, NOT a line-oriented
>   editor.  Would you want it to skip to the next line after each
>   replacement if the strings were (say) "abc" and ""?  
>
>No, it shouldn't skip to the next line, but it SHOULD skip past the
>previously matched string.  i.e. replacing "foo bar" with "foo" should not
>change "foo bar bar " to "foo", it should become "foo bar".  A replacement
>should not be re-run on the results of the replacement.  Effectively, a
>replace-<whatever> should look like it found all non-overlapping occurences
>of the search item first, and then did the change second.  For a similar 
>example, should the null op (replace-string "a" "a") be an infinite loop?

But it did skip past the previously matched string.  The problem is in
the semantics of "^" in regexps.  When point is at the beginning of a
line, which side of the "^" is it on?  I think you are arguing that
before the replace starts, the point on the left of it (to pick up the
match on the first line), but after the first replace, point is on the
right of it (to avoid repetition).  I can see the logic for this
semantics.  The character-orientedness isn't really the problem, it is
the precise semantics of the non-character "^".  From info:

`^'     
     is a special character that matches the empty string, but only if at
     the beginning of a line in the text being matched.  Otherwise it fails
     to match anything.  Thus, `^foo' matches a `foo' which occurs
     at the beginning of a line.
     
This would have to change to:

`^'     
     is a special character that matches the empty string, but only if at
     the beginning of a line in the text being matched.  Otherwise it fails
     to match anything.  Thus, `^foo' matches a `foo' which occurs
     at the beginning of a line.  Once a `^' has been matched in a
     repeated search, it will fail to match the beginning of the same
     line.

Or some such.  I find it very hard to express this idea.  Maybe
something more along the lines of "when a search starts, the beginning
of each line is found and the first character on each line, if any, is
marked.  These characters are the only ones that will match in the
position following a `^' in a search pattern until the completion of
the repeated search."

I find the original concept more powerful and elegant.  Once you
change the behavior, getting the original behavior back would be a lot
more tedious as well.  You'd want a way to re-mark the beginnings of
all lines or soemthing.  Or two varieties of `^'...

Enough rambling...
--
     

/jr
jr@bbn.com or bbn!jr
C'mon big money!

peck@SUN.COM (04/14/89)

If you want it to match and skip the newline, just say so:

(replace-regexp "\n." "\n" nil)

As John correctly points out, the semantice of "^" and "\n" are different.

huxtable@kuhub.cc.ukans.edu (Kathryn Huxtable) (04/16/89)

In article <8904130343.AA05725@starbase>, israel@STARBASE.MITRE.ORG (Bruce Israel) writes:
>    From: mailrus!sharkey!itivax!umich!zip!spencer@purdue.edu  (Spencer W. Thomas)
> 
>    In some article loic%axis_d@axis.axis.fr writes:
> 
>    >   (replace-regexp "^." "" ())
>    >   It empties my buffer !
>    >   It should skip to the next new-line. Don't you think so ?
> 
>    Well, no.  Emacs is a character-oriented editor, NOT a line-oriented
>    editor.  Would you want it to skip to the next line after each
>    replacement if the strings were (say) "abc" and ""?  
> 
> No, it shouldn't skip to the next line, but it SHOULD skip past the
> previously matched string.  [stuff deleted]  A replacement
> should not be re-run on the results of the replacement.  Effectively, a
> replace-<whatever> should look like it found all non-overlapping occurences
> of the search item first, and then did the change second.  For a similar 
> example, should the null op (replace-string "a" "a") be an infinite loop?
> 
> I think that the workarounds given for this problem are excessively
> complicated for the task the guy is trying to perform.

I hate beating a dead fish, but regular expressions are dear to my
heart.  I agree completely.  "Natural" regular expressions should
replace the natural thing.  The workarounds were convoluted.  I know
that "natural" is sometimes hard to pin down, but I don't think this
is such a case.

-Kathryn Huxtable
huxtable@kuhub.cc.ukans.edu

shap@polya.Stanford.EDU (Jonathan S. Shapiro) (04/16/89)

I was going to stay out of this, but it is relevant to observe that
the whole beginning-of-line concept is a meta-concept,
beginning-of-line not being in the domain of characters when
distinguished from end-of-line.

Given this, we can argue what beginning of line should do.

It is certainly desirable, however, that a regular expression
never be permitted to match a given input item (either character, BOL,
or EOL) in more than one string-to-be-replaced.


Jon