Replace with uppercase characters with gsub - ruby

I have nubmers of simple strings 'som', 'man', 'pal', etc
How do i make vowel character upcase!, having vowel regex or array to have output like 'sOm', 'pAl', 'mAn' ?

"som".gsub(/[aeiou]/, &:upcase)
# => "sOm"
or
"som".tr("aeiou", "AEIOU")
# => "sOm"

Related

Ruby regex to extract match_group value?

I have two questions about regex.
The match string is:
"FuR6UcUiduzPyenxCSzZbDXTge3f3t9ufA, user_email=admin#example.com"
When extracting the user_email value, my regexp is:
\s+(?<email_from_header>\S+)
and the match group value is:
(space)user_email=admin#example.com"
What do I use to omit the first (space) char and the last " quote?
When extracting the token, my regex is:
AUTH-TOKEN\s+(?<auth_token>\S+)
and the match group value is:
FuR6UcUiduzPyenxCSzZbDXTge3f3t9ufA,
What do I use to delete that last trailing comma ,?
Your regex would be,
\s+\K(?<email_from_header>[^"]*)
Use \K switch to discard the previously matched characters. And use not character class to match any character not of " zero or more times.
Your regex would be,
AUTH-TOKEN\s+(?<auth_token>[^,]*)
[^,]* it would match any character not of , zero or more times.
If your string has embedded double-quotes:
str[/^"(.+),/, 1] # => "FuR6UcUiduzPyenxCSzZbDXTge3f3t9ufA"
str[/^"(.+?),/, 1] # => "FuR6UcUiduzPyenxCSzZbDXTge3f3t9ufA"
str[/^"([^,]+),/, 1] # => "FuR6UcUiduzPyenxCSzZbDXTge3f3t9ufA"
str = '"FuR6UcUiduzPyenxCSzZbDXTge3f3t9ufA, user_email=admin#example.com"'
str # => "\"FuR6UcUiduzPyenxCSzZbDXTge3f3t9ufA, user_email=admin#example.com\""
str[/(user_email=.+)"/, 1] # => "user_email=admin#example.com"
str[/(user_email=[^"]+)"/, 1] # => "user_email=admin#example.com"
str[/user_email=([^"]+)"/, 1] # => "admin#example.com"
match = str.match(/(?<user_email>user_email=(?<addr>.+))"/)
match # => #<MatchData "user_email=admin#example.com\"" user_email:"user_email=admin#example.com" addr:"admin#example.com">
match['user_email'] # => "user_email=admin#example.com"
match['addr'] # => "admin#example.com"
If it doesn't:
str = 'FuR6UcUiduzPyenxCSzZbDXTge3f3t9ufA, user_email=admin#example.com'
str # => "FuR6UcUiduzPyenxCSzZbDXTge3f3t9ufA, user_email=admin#example.com"
str[/^(.+),/, 1] # => "FuR6UcUiduzPyenxCSzZbDXTge3f3t9ufA"
str[/^(.+?),/, 1] # => "FuR6UcUiduzPyenxCSzZbDXTge3f3t9ufA"
str[/^([^,]+),/, 1] # => "FuR6UcUiduzPyenxCSzZbDXTge3f3t9ufA"
str[/(user_email=.+)/, 1] # => "user_email=admin#example.com"
str[/(user_email=(.+))/, 2] # => "admin#example.com"
str[/user_email=(.+)/, 1] # => "admin#example.com"
Or, having more regex fun:
match = str.match(/(?<user_email>user_email=(?<addr>.+))/)
match # => #<MatchData "user_email=admin#example.com" user_email:"user_email=admin#example.com" addr:"admin#example.com">
match['user_email'] # => "user_email=admin#example.com"
match['addr'] # => "admin#example.com"
Regular expressions are a very rich language, and you can write something in many ways usually. The problem then becomes maintaining the pattern as the program "matures". I recommend starting simply, and expanding the pattern as the needs dictate. Don't start complex hoping to find a working solution, because that usually doesn't work; Getting a complex pattern to work immediately often fails.

How can I upcase first occurrence of an alphabet in alphanumeric string?

Is there any easy way to convert strings like 3500goat to 3500Goat and goat350rat to Goat350rat?
I am trying to convert the first occurrence of alphabet in an alphanumeric string to uppercase. I was trying the code below using the method sub, but no luck.
stringtomigrate = 3500goat
stringtomigrate.sub!(/\D{0,1}/) do |w|
w.capitalize
This should work:
string.sub(/[a-zA-Z]/) { |s| s.upcase }
or a shorthand:
string.sub(/[a-zA-Z]/, &:upcase)
examples:
'3500goat'.sub(/[a-zA-Z]/, &:upcase)
# => "3500Goat"
'goat350rat'.sub(/[a-zA-Z]/, &:upcase)
# => "Goat350rat"
Try this
1.9.3-p545 :060 > require 'active_support/core_ext'
=> true
1.9.3-p545 :099 > "goat350rat to Goat350rat".sub(/[a-zA-Z]/){ |x| x.titleize}
=> "Goat350rat to Goat350rat"

Why does sub replace only one character with a regex?

I would like to strip all non-digit characters from a string.
/\D/ is a non-digit character ([^0-9]):
irb(main):010:0> s = "(123) 456-7890"
=> "(123) 456-7890"
irb(main):011:0> s.sub( /\D*/, '' )
=> "123) 456-7890"
Do as below using String#tr or String#gsub:
s.gsub(/[[:punct:]]|[[:space:]]/ ,'')
# => "1234567890"
s.tr('^0-9','') # even more faster
# => "1234567890"
sub replaces once. gsub replaces all.
Use gsub instead:
s.gsub( /\D/, '' )

Regex: match word breaks that are not "="

How does one match all \b that are not "="?
"igloo".match(...) # => `igloo`
"igloo=".match(...) # => `nil`
First, \b doesn't match '='; it matches on the boundary between '=' and something else. To match only when the other side of the boundary is not '=', use a negative lookahead:
rx = /igloo\b(?!=)/
"igloo".match(rx) => #<MatchData "igloo">
"igloo=".match(rx) => nil
That says "match a \b boundary, but only when not followed by '='".

Ruby multiple string replacement

str = "Hello☺ World☹"
Expected output is:
"Hello:) World:("
I can do this: str.gsub("☺", ":)").gsub("☹", ":(")
Is there any other way so that I can do this in a single function call?. Something like:
str.gsub(['s1', 's2'], ['r1', 'r2'])
Since Ruby 1.9.2, String#gsub accepts hash as a second parameter for replacement with matched keys. You can use a regular expression to match the substring that needs to be replaced and pass hash for values to be replaced.
Like this:
'hello'.gsub(/[eo]/, 'e' => 3, 'o' => '*') #=> "h3ll*"
'(0) 123-123.123'.gsub(/[()-,. ]/, '') #=> "0123123123"
In Ruby 1.8.7, you would achieve the same with a block:
dict = { 'e' => 3, 'o' => '*' }
'hello'.gsub /[eo]/ do |match|
dict[match.to_s]
end #=> "h3ll*"
Set up a mapping table:
map = {'☺' => ':)', '☹' => ':(' }
Then build a regex:
re = Regexp.new(map.keys.map { |x| Regexp.escape(x) }.join('|'))
And finally, gsub:
s = str.gsub(re, map)
If you're stuck in 1.8 land, then:
s = str.gsub(re) { |m| map[m] }
You need the Regexp.escape in there in case anything you want to replace has a special meaning within a regex. Or, thanks to steenslag, you could use:
re = Regexp.union(map.keys)
and the quoting will be take care of for you.
You could do something like this:
replacements = [ ["☺", ":)"], ["☹", ":("] ]
replacements.each {|replacement| str.gsub!(replacement[0], replacement[1])}
There may be a more efficient solution, but this at least makes the code a bit cleaner
Late to the party but if you wanted to replace certain chars with one, you could use a regex
string_to_replace.gsub(/_|,| /, '-')
In this example, gsub is replacing underscores(_), commas (,) or ( ) with a dash (-)
Another simple way, and yet easy to read is the following:
str = '12 ene 2013'
map = {'ene' => 'jan', 'abr'=>'apr', 'dic'=>'dec'}
map.each {|k,v| str.sub!(k,v)}
puts str # '12 jan 2013'
You can also use tr to replace multiple characters in a string at once,
Eg., replace "h" to "m" and "l" to "t"
"hello".tr("hl", "mt")
=> "metto"
looks simple, neat and faster (not much difference though) than gsub
puts Benchmark.measure {"hello".tr("hl", "mt") }
0.000000 0.000000 0.000000 ( 0.000007)
puts Benchmark.measure{"hello".gsub(/[hl]/, 'h' => 'm', 'l' => 't') }
0.000000 0.000000 0.000000 ( 0.000021)
Riffing on naren's answer above, I'd go with
tr = {'a' => '1', 'b' => '2', 'z' => '26'}
mystring.gsub(/[#{tr.keys}]/, tr)
So
'zebraazzeebra'.gsub(/[#{tr.keys}]/, tr) returns
"26e2r112626ee2r1"

Resources