get the number from string by regex - ruby

I have a string like this:
"com.abcd.efghi.pay.0.99"
"com.abcd.efghi.pay.9.99"
"com.abcd.efghi.pay.19.99"
I want get the number(0.99, 9.99, 19.99). I tried to do like this:
"com.abcd.efghi.pay.0.99".scan(/\d/).join
=> "099"
Anyone can help me get the correct result. Thanks in advance!

"com.abcd.efghi.pay.0.99".split(/\D+/, 2).last # => "0.99"
"com.abcd.efghi.pay.9.99".split(/\D+/, 2).last # => "9.99"
"com.abcd.efghi.pay.19.99".split(/\D+/, 2).last # => "19.99"
or
"com.abcd.efghi.pay.0.99".sub(/\D+/, "") # => "0.99"
"com.abcd.efghi.pay.9.99".sub(/\D+/, "") # => "9.99"
"com.abcd.efghi.pay.19.99".sub(/\D+/, "") # => "19.99"

This is pretty simple, regexp for numbers like 0.00 or 00.00:
\d{1,2}.{2,}
\d Any digit
\d{1,2} Between 1 and 2 of digit
. a dot
\d{2,} 2 or more of digit
Example:
>> "com.abcd.efghi.pay.19.99"[/\d{1,2}.{2,}/, 0]
=> "19.99"
>> "com.abcd.efghi.pay.9.99"[/\d{1,2}.{2,}/, 0]
=> "9.99"

You probably want something like this:
\d+(\.\d+)?
which looks for an integer followed by an optional fractional part.

Something like this:
"com.abcd.efghi.pay.0.99".scan(/(\d+[.]\d+)/).flatten.first
# => "0.99"

Without regex:
str = "com.abcd.efghi.pay.0.99"
str.split(".").last(2).join(".") # => "0.99"

You can use this regex in scan:
\b\d+(?:\.\d+)?

You need to use end of the line anchor.
\b\d+(?:\.\d+)?$

Ah, so many ways. Here are a couple more:
str = "com.abcd.efghi.pay.9.99"
str[str.index(/\d/)..-1] #=> "9.99"
str.sub(/.*?(?=\d)/,'') #=> "9.99"

Related

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"

Ruby Split Integer Into Array

I have this value x = 876885 . I want to split that value into the array like [876,885]
This is what I tried
x.to_s[0..2].split(',') #=> ["876"]
How can I get something like [876,885]?
Similar to DigitalRoss's answer.
x.divmod(1000)
[x/1000, x%1000] # => [876, 885]
How's about this:
x = 876885
x.to_s.scan(/.../).map {|e| e.to_i }
=> [876, 885]
If you want to be able to handle numbers of arbitrary length, then you can do it using each_slice:
876885.to_s.each_char.each_slice(3).map{|x| x.join}
How about this?
[x.to_s[0..2], x.to_s[3..-1]]
#DigitalRoss's solution is the best for 6-digit numbers, but here's a more general one:
a = 876885
a.to_s.chars.each_slice(3).map { |a| a.join.to_i }
# ⇒ [
# [0] 876,
# [1] 885
#]

Squeeze double char in Ruby

What is the best way to squeeze multicharacter in string ?
Example:
hahahahahaha => ha
lalalala => la
awdawdawdawd => awd
str.squeeze("ha") # doesn't work
str.tr("haha", "ha") # doesn't work
def squeeze(s)
s.gsub(/(.+?)\1+/, '\1')
end
puts squeeze('hahahaha') # => 'ha'
puts squeeze('awdawdawd') # => 'awd'
puts squeeze('hahahaha something else') # => 'ha something else'
You can use regex based search and replace:
str.gsub(/(ha)+/, 'ha')

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"

Ruby array to string conversion

I have a ruby array like ['12','34','35','231'].
I want to convert it to a string like '12','34','35','231'.
How can I do that?
I'll join the fun with:
['12','34','35','231'].join(', ')
# => 12, 34, 35, 231
EDIT:
"'#{['12','34','35','231'].join("', '")}'"
# => '12','34','35','231'
Some string interpolation to add the first and last single quote :P
> a = ['12','34','35','231']
> a.map { |i| "'" + i.to_s + "'" }.join(",")
=> "'12','34','35','231'"
try this code ['12','34','35','231']*","
will give you result "12,34,35,231"
I hope this is the result you, let me know
array.map{ |i| %Q('#{i}') }.join(',')
string_arr.map(&:inspect).join(',') # or other separator
I find this way readable and rubyish:
add_quotes =- > x{"'#{x}'"}
p ['12','34','35','231'].map(&add_quotes).join(',') => "'12','34','35','231'"
> puts "'"+['12','34','35','231']*"','"+"'"
'12','34','35','231'
> puts ['12','34','35','231'].inspect[1...-1].gsub('"',"'")
'12', '34', '35', '231'
And yet another variation
a = ['12','34','35','231']
a.to_s.gsub(/\"/, '\'').gsub(/[\[\]]/, '')
irb(main)> varA
=> {0=>["12", "34", "35", "231"]}
irb(main)> varA = Hash[*ex.collect{|a,b| [a,b.join(",")]}.flatten]
...
irb(main):027:0> puts ['12','34','35','231'].inspect.to_s[1..-2].gsub('"', "'")
'12', '34', '35', '231'
=> nil
You can use some functional programming approach, transforming data:
['12','34','35','231'].map{|i| "'#{i}'"}.join(",")
suppose your array :
arr=["1","2","3","4"]
Method to convert array to string:
Array_name.join(",")
Example:
arr.join(",")
Result:
"'1','2','3','4'"
array.inspect.inspect.gsub(/\[|\]/, "") could do the trick

Resources