Reputation: 145
Let's say I had a string "I have 36 dogs in 54 of my houses in 24 countries". Is it possible by using only gsub to add a " " between each digit so that the string becomes "I have 3 6 dogs in 5 4 of my houses in 2 4 countries"?
gsub(/(\d)(\d)/, "#{$1} #{$2}")
does not work as it replaces each digit with a space and neither does gsub(/\d\d/, "\d \d")
, which replaces the each digit with d
.
Upvotes: 2
Views: 2443
Reputation: 110675
s = "I have 3651 dogs in 24 countries"
Four ways to use String#gsub:
Use a positive lookahead and capture group
r = /
(\d) # match a digit in capture group 1
(?=\d) # match a digit in a positive lookahead
/x # extended mode
s.gsub(r, '\1 ')
#=> "I have 3 6 5 1 dogs in 2 4 countries"
A positive lookbehind could be used as well:
s.gsub(/(?<=\d)(\d)/, ' \1')
Use a block
s.gsub(/\d+/) { |s| s.chars.join(' ') }
#=> "I have 3 6 5 1 dogs in 2 4 countries"
Use a positive lookahead and a block
s.gsub(/\d(?=\d)/) { |s| s + ' ' }
#=> "I have 3 6 5 1 dogs in 2 4 countries"
Use a hash
h = '0'.upto('9').each_with_object({}) { |s,h| h[s] = s + ' ' }
#=> {"0"=>"0 ", "1"=>"1 ", "2"=>"2 ", "3"=>"3 ", "4"=>"4 ",
# "5"=>"5 ", "6"=>"6 ", "7"=>"7 ", "8"=>"8 ", "9"=>"9 "}
s.gsub(/\d(?=\d)/, h)
#=> "I have 3 6 5 1 dogs in 2 4 countries"
Upvotes: 2
Reputation: 4348
An alternative way is to look for the place between the numbers using lookahead and lookbehind and then just replace that with a space.
[1] pry(main)> s = "I have 36 dogs in 54 of my houses in 24 countries"
=> "I have 36 dogs in 54 of my houses in 24 countries"
[2] pry(main)> s.gsub(/(?<=\d)(?=\d)/, ' ')
=> "I have 3 6 dogs in 5 4 of my houses in 2 4 countries"
Upvotes: 1
Reputation: 176382
In order to reference a match you should use \n
where n
is the match, not $1
.
s = "I have 36 dogs in 54 of my houses in 24 countries"
s.gsub(/(\d)(\d)/, '\1 \2')
# => "I have 3 6 dogs in 5 4 of my houses in 2 4 countries"
Upvotes: -1