[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

scan regular expression and strings

STEPHEN BECKER I V

9/29/2004 2:34:00 PM

tr="meet"
tr.scan(/(.)\1/) {|x| x=x+'x'}
print tr

What I want it to do is find doubles like the ee in meet and put an x
between them. Am i doing this wrong because x is part of an array now?


5 Answers

Brian Schröder

9/29/2004 2:50:00 PM

0

STEPHEN BECKER I V wrote:

>tr="meet"
>tr.scan(/(.)\1/) {|x| x=x+'x'}
>print tr
>
>What I want it to do is find doubles like the ee in meet and put an x
>between them. Am i doing this wrong because x is part of an array now?
>
>
>
Your change to x is local to the block, because x is a new string object
on each iteration, that is not connected to tr.
You can achieve your aim like this:

Warning: Untested, but the idea should be clear.

x = "meet meep meep"
y = x.gsub(/(.)(\1)/, '\1x\2')

Observe that this does not change the string x, but the result will be
allocated in y.
If you want to change the original string use gsub!.

Regards,

Brian


Andrew Johnson

9/29/2004 3:00:00 PM

0

On Wed, 29 Sep 2004 23:34:25 +0900, STEPHEN BECKER I V
<Becker004@gmail.com> wrote:
> tr="meet"
> tr.scan(/(.)\1/) {|x| x=x+'x'}
> print tr
>
> What I want it to do is find doubles like the ee in meet and put an x
> between them. Am i doing this wrong because x is part of an array now?

You want to use .gsub! instead of .scan. A simple approach:

tr="meet"
tr.gsub!(/(.)(\1)/, '\1X\2')
print tr

Of course if you want "meeet" to become "meXeXet" then the above
won't be good enough and you'll want to use look-aheads to avoid
consuming each following 'e':

tr="meeet"
tr.gsub!(/(.)(?=\1)/, '\1X')
print tr

regards,
andrew

Ryan Flynn

9/29/2004 3:51:00 PM

0

> x = "meet meep meep"
> y = x.gsub(/(.)(\1)/, '\1x\2')

$ irb
irb(main):001:0> $_="meeet"
=> "meeet"
irb(main):002:0> gsub(/(.)(\1)/, '\1x\2')
=> "mexeet"
irb(main):003:0> gsub(/(.)\1/, '\1x\1')
=> "mexexet"
irb(main):004:0>

i figured it'd be more efficient not to capture the second instance,
and just use \1 again in the replacement since it's the same
character; however, i also got a different ("more correct" i think)
result... do ruby regexes not advance past what they don't capture? i
expected the second one to be slightly more efficient but i expected
the behavior to be identical... can anyone shed some light?


ts

9/29/2004 3:57:00 PM

0

>>>>> "R" == Ryan Flynn <parseerror@gmail.com> writes:

R> $ irb
R> irb(main):001:0> $_="meeet"
R> => "meeet"
R> irb(main):002:0> gsub(/(.)(\1)/, '\1x\2')
R> => "mexeet"
R> irb(main):003:0> gsub(/(.)\1/, '\1x\1')
R> => "mexexet"
R> irb(main):004:0>

svg% irb
irb(main):001:0> $_="meeet"
=> "meeet"
irb(main):002:0> gsub(/(.)\1/, '\1x\1')
=> "mexeet"
irb(main):003:0> gsub(/(.)(\1)/, '\1x\2')
=> "mexexet"
irb(main):004:0>

R> the behavior to be identical... can anyone shed some light?

You work with $_ which is modified, i.e.

svg% irb
irb(main):001:0> $_="meeet"
=> "meeet"
irb(main):002:0> gsub(/(.)\1/, '\1x\1')
=> "mexeet"
irb(main):003:0> $_
=> "mexeet"
irb(main):004:0> gsub(/(.)\1/, '\1x\1')
=> "mexexet"
irb(main):005:0> $_
=> "mexexet"
irb(main):006:0>




Guy Decoux




Ryan Flynn

9/29/2004 4:03:00 PM

0

d'oh, you're right. tricked up by my own laziness.