[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

One-liner for regex subsitition (with upcasing)!

Ian Amuhton

1/7/2006 5:27:00 PM

Looking at Steve Litt's Basic Ruby Tutorial at ...

<http://www.troubleshooters.com/codecorn/ruby/basictutori...

says he's found no easy way to replace the *first* occurrance of a regex
match in a string with it's uppercase equivalent. I got intrigued and
decided to see if I (rank noob) might take a stab at it.

Here's what I came up with, using Steve's framework as a base:

#!/usr/bin/env ruby

string1 = "I will drill for a well in walla walla washington."
string2 = string1.dup

def methodA(s) # this works, but requires 2 lines
regex = /w.ll/
s.sub(regex, regex.match(s)[0].upcase)
end

def methodB(s) # this doesn't work, "will" stays lowercase
s.sub(/w.ll/, '\0'.upcase)
end

puts "Original: " + string1 + "\nMethod A: " + methodA(string1)

puts "\n\nOriginal: " + string2 + "\nMethod B: " + methodB(string2)


methodA() returns:

I WILL drill for a well in walla walla washington.

but "will" is still lowercase after methodB(). How might the one-liner
in methodB() be successfully rewritten?


--
da
~~


3 Answers

Robert Klemme

1/7/2006 6:09:00 PM

0

Donkey Agony <root@[127.0.0.1]> wrote:
> Looking at Steve Litt's Basic Ruby Tutorial at ...
>
> <http://www.troubleshooters.com/codecorn/ruby/basictutori...
>
> says he's found no easy way to replace the *first* occurrance of a
> regex match in a string with it's uppercase equivalent. I got
> intrigued and decided to see if I (rank noob) might take a stab at it.
>
> Here's what I came up with, using Steve's framework as a base:
>
> #!/usr/bin/env ruby
>
> string1 = "I will drill for a well in walla walla washington."
> string2 = string1.dup
>
> def methodA(s) # this works, but requires 2 lines
> regex = /w.ll/
> s.sub(regex, regex.match(s)[0].upcase)
> end

It's especially silly as it matches the RX *twice* against the string.

> def methodB(s) # this doesn't work, "will" stays lowercase
> s.sub(/w.ll/, '\0'.upcase)
> end

Of course, you just upcase the string '\0'. Your call is equivalent to

s.sub(/w.ll/, '\0')

> puts "Original: " + string1 + "\nMethod A: " > + methodA(string1)
>
> puts "\n\nOriginal: " + string2 + "\nMethod B: " > + methodB(string2)
>
>
> methodA() returns:
>
> I WILL drill for a well in walla walla washington.
>
> but "will" is still lowercase after methodB(). How might the
> one-liner in methodB() be successfully rewritten?

You want the block form of sub:

>> "I will drill for a well in walla walla washington.".sub(/w.ll/){|m|
>> m.upcase}
=> "I WILL drill for a well in walla walla washington."

>> "I will drill for a well in walla walla washington.".sub(/w.ll/){|m|
>> m.upcase!}
=> "I WILL drill for a well in walla walla washington."

It's the only reasonable thing to do here because you won't know the matched
text before the RX actually matched and that is the point in time where you
have to calculate the replacement. The non block form calculates the
replacement *before* the invocation - of course you can use \\0, \\1 etc, to
access parts - but you can't modify them.

Kind regards

robert


Ian Amuhton

1/7/2006 6:48:00 PM

0

Robert Klemme wrote:
>> def methodB(s) # this doesn't work, "will" stays lowercase
>> s.sub(/w.ll/, '\0'.upcase)
>> end

> You want the block form of sub:
>
>>> "I will drill for a well in walla walla washington.".sub(/w.ll/){|m|
>>> m.upcase}
> => "I WILL drill for a well in walla walla washington."

Ahhhhhhh.

>>> "I will drill for a well in walla walla washington.".sub(/w.ll/){|m|
>>> m.upcase!}
> => "I WILL drill for a well in walla walla washington."

What's the difference between `upcase` and `upcase!` in these instances
(i.e., inside the block)? In irb, those both seem to yield the same
result. In a program, I had to use `sub!` if modifying the variable
directly, i.e.:

string1 = "I will drill for a well in walla walla washington."
string1.sub!(/w.ll/) { |m| m.upcase }
puts string1

(also same result whether using `upcase` or `upcase!` in the block...)

> It's the only reasonable thing to do here because you won't know the
> matched text before the RX actually matched and that is the point in
> time where you have to calculate the replacement. The non block form
> calculates the replacement *before* the invocation - of course you
> can use \\0, \\1 etc, to access parts - but you can't modify them.

Bingo! It's so obvious once you see it. :)

Thank you, Robert!

--
da
~~


Robert Klemme

1/7/2006 10:35:00 PM

0

Donkey Agony <root@[127.0.0.1]> wrote:
> Robert Klemme wrote:
>>> def methodB(s) # this doesn't work, "will" stays lowercase
>>> s.sub(/w.ll/, '\0'.upcase)
>>> end
>
>> You want the block form of sub:
>>
>>>> "I will drill for a well in walla walla
>>>> washington.".sub(/w.ll/){|m| m.upcase}
>> => "I WILL drill for a well in walla walla washington."
>
> Ahhhhhhh.

I hope nobody's hurt. :-)

>>>> "I will drill for a well in walla walla
>>>> washington.".sub(/w.ll/){|m| m.upcase!}
>> => "I WILL drill for a well in walla walla washington."
>
> What's the difference between `upcase` and `upcase!` in these
> instances (i.e., inside the block)? In irb, those both seem to yield
> the same result. In a program, I had to use `sub!` if modifying the
> variable directly, i.e.:

upcase! modifies in place - but it's not a problem here as the match string
is a new instance anyway. In this case it boils down to upcase! being more
efficint.

> string1 = "I will drill for a well in walla walla washington."
> string1.sub!(/w.ll/) { |m| m.upcase }
> puts string1
>
> (also same result whether using `upcase` or `upcase!` in the block...)

Same story.

>> It's the only reasonable thing to do here because you won't know the
>> matched text before the RX actually matched and that is the point in
>> time where you have to calculate the replacement. The non block form
>> calculates the replacement *before* the invocation - of course you
>> can use \\0, \\1 etc, to access parts - but you can't modify them.
>
> Bingo! It's so obvious once you see it. :)
>
> Thank you, Robert!

You're welcome!

robert