[comp.lang.perl] Need help with

gorpong@uunet.uu.net (11/05/90)

Something is a little strange either with the way that I am interpreting the
manual page, or with Perl.  The mini-script:

	$string = "this is a test of stuff\t95";
	($a = $string) =~ s/\w+\s+(\d+)/$1/;
	print "1 == $1\nA == $a\n+ == $+\nbefore == $`\nafter == $'\n";

Prints out:

	1 == 95
	A == this is a test of 95
	+ == 95
	before == this is a test of 
	after == 

I think it should print out:

	1 == 95
	A == 95
	+ == 95
	before == this is a test of
	after ==

Why is 'a' not correctly being substituted?  Or is it doing exactly what it
should be doing, and I am the one confused?

		-- Gordon.

--
Gordon C. Galligher	9127 Potter Rd. #2E	Des. Plaines, Ill.    60016-4881
     telxon!ping%gorpong@uunet.uu.net (not tested)  (Is this even legal??)
     ...!uunet!telxon!ping!gorpong      (tested)    (And it works!)
"It seems to me, Golan, that the advance of civilization is nothing but an
 exercise in the limiting of privacy." - Janov Pelorat -- _Foundation's Edge_

gustav@tharr.UUCP (Paul Moore) (11/06/90)

In article <1990Nov4.224658.21882@uvaarpa.Virginia.EDU> telxon!ping!gorpong@uunet.uu.net writes:
>Something is a little strange either with the way that I am interpreting the
>manual page, or with Perl.  The mini-script:
>
>	$string = "this is a test of stuff\t95";
>	($a = $string) =~ s/\w+\s+(\d+)/$1/;
>	print "1 == $1\nA == $a\n+ == $+\nbefore == $`\nafter == $'\n";
>
>Prints out:
>
>	1 == 95
>	A == this is a test of 95
>	+ == 95
>	before == this is a test of 
>	after == 

This is correct.

The substitution is editing $a, not replacing it. The expression on the
second line works like this. First, you assign $string to $a, setting $a
to "this is a test of stuff\t95". This assignment returns an LVALUE, $a.
The =~ operator then applies the following substitution to this value.

s/\w+\s+(\d+)/$1/ looks through the string for a word (\w+) followed by
whitespace (\s+) followed by a number (\d+), finding "stuff\t95" in this
case. It then replaces this part of the string with the number ($1), but
*leaving the rest of the string as it was*. So, the result is "this is a
test of 95", as shown.

If you really do want $a to equal "95", you could just say $a = $1 at
the end ($1 keeps its value outside the replacement pattern). I'm sure
there are better ways, as well. (but I'm too tired to think of one just
now...)

Hope this helps,
Gustav.
-- 
/----------------------------------------------------------------\
| Paul Moore              E-Mail:    ...!ukc!tharr!gustav        |
| 10, Mulberry Rise       or         ...!ukc!cix!pmoore          |
| Northwich, Cheshire     or (BEST)  pmoore@cix.compulink.co.uk  |
<-- tharr *free* public access to Usenet in the UK 0234 261804 -->

worley@compass.uucp (Dale Worley) (11/06/90)

   From: gustav@tharr.UUCP (Paul Moore)

   >	($a = $string) =~ s/\w+\s+(\d+)/$1/;

   If you really do want $a to equal "95", you could just say $a = $1 at
   the end ($1 keeps its value outside the replacement pattern). I'm sure
   there are better ways, as well. (but I'm too tired to think of one just
   now...)

($a) = $string =~ s/\w+\s+(\d+)/$1/;

Dale Worley		Compass, Inc.			worley@compass.com
--
Bring your mistress!  Bring your boyfriend!  Bring your wife!
-- La Cage aux Folles

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (11/07/90)

In article <1990Nov6.153943.14710@uvaarpa.Virginia.EDU> worley@compass.uucp writes:
: 
:    From: gustav@tharr.UUCP (Paul Moore)
: 
:    >	($a = $string) =~ s/\w+\s+(\d+)/$1/;
: 
:    If you really do want $a to equal "95", you could just say $a = $1 at
:    the end ($1 keeps its value outside the replacement pattern). I'm sure
:    there are better ways, as well. (but I'm too tired to think of one just
:    now...)
: 
: ($a) = $string =~ s/\w+\s+(\d+)/$1/;

Well, no, actually.  I've never made s/// do anything special in array context.
Terminal laziness, I guess.

Larry

worley@compass.uucp (Dale Worley) (11/07/90)

   From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall)

   From: Dale Worley
   : ($a) = $string =~ s/\w+\s+(\d+)/$1/;

   Well, no, actually.  I've never made s/// do anything special in array context.
   Terminal laziness, I guess.

Duh.  I thought I used it, but it was really a m//, not an s///.
Memo to self:  Check code before posting it.

Dale Worley		Compass, Inc.			worley@compass.com
--
Crucifixes are sexy because there's a naked man on them. -- Madonna

gorpong@ping.uucp (Gordon C. Galligher) (11/11/90)

In article <1990Nov4.224658.21882@uvaarpa.Virginia.EDU> telxon!ping!gorpong@uunet.uu.net writes:
>Something is a little strange either with the way that I am interpreting the
>manual page, or with Perl.  The mini-script:
[...confusion on \w+ mini-script deleted...]

Thank you all very much for your help; as is normally the case you are right
and I am stupid.

Well, this is another case where TFM and I were not on the same wavelength.
Of course the manual states that \w matches a word CHARACTER, not an entire
word, and the + just tells it to match more than one word character; and
that match would stop when a whitespace character came up.

I may have been able to see it if I had really LOOKED at my output.  I did
not see the fact that "stuff\t95" had been replaced with 95; or I may have
saved this group the trouble of this bandwidth.  My apologies.  Just as
a quick aside, what I wanted to do was:
	REPLACE one or more words followed by one or more whitespace
	        characters followed by one or more digits
	WITH	just the digits
Other than changing the s/// to m// and using $1 outside, is there any easy
way to do that from within a =~ expression?

(Did you recognize the s/\w+.../$1/ expression Larry? :-)

		-- Gordon.
-- 
Gordon C. Galligher	9127 Potter Rd. #2E	Des. Plaines, Ill.    60016-4881
	     ...!uunet!telxon!teleng!ping!gorpong

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (11/13/90)

In article <1990Nov10.160720.7715@ping.uucp> gorpong@ping.uucp (Gordon C. Galligher) writes:
: Just as a quick aside, what I wanted to do was:
: 	REPLACE one or more words followed by one or more whitespace
: 	        characters followed by one or more digits
: 	WITH	just the digits
: Other than changing the s/// to m// and using $1 outside, is there any easy
: way to do that from within a =~ expression?

Something like:

	s/(\S+\s+)+(\d+)/$2/g;

That's called "thinking positively"...

Larry