Why does sub replace only one character with a regex? - ruby

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/, '' )

Related

Ruby - regex that matches string to pattern and detects unwanted occurrences [duplicate]

How do I a string against a regex such that it will return true if the whole string matches (not a substring)?
eg:
test( \ee\ , "street" ) #=> returns false
test( \ee\ , "ee" ) #=> returns true!
Thank you.
You can match the beginning of the string with \A and the end with \Z. In ruby ^ and $ match also the beginning and end of the line, respectively:
>> "a\na" =~ /^a$/
=> 0
>> "a\na" =~ /\Aa\Z/
=> nil
>> "a\na" =~ /\Aa\na\Z/
=> 0
This seems to work for me, although it does look ugly (probably a more attractive way it can be done):
!(string =~ /^ee$/).nil?
Of course everything inside // above can be any regex you want.
Example:
>> string = "street"
=> "street"
>> !(string =~ /^ee$/).nil?
=> false
>> string = "ee"
=> "ee"
>> !(string =~ /^ee$/).nil?
=> true
Note: Tested in Rails console with ruby (1.8.7) and rails (3.1.1)
So, what you are asking is how to test whether the two strings are equal, right? Just use string equality! This passes every single one of the examples that both you and Tomas cited:
'ee' == 'street' # => false
'ee' == 'ee' # => true
"a\na" == 'a' # => false
"a\na" == "a\na" # => true

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"

how to remove backslash from a string containing an array in ruby

I have a string like this
a="[\"6000208900\",\"600020890225\",\"600900231930\"]"
#expected result [6000208900,600020890225,600900231930]
I am trying to remove the backslash from the string.
a.gsub!(/^\"|\"?$/, '')
Inside the double quoted string(""), another double quotes must be escaped by \. You can't remove it.
Use puts, you can see it is not there.
a = "[\"6000208902912790\"]"
puts a # => ["6000208902912790"]
Or use JSON
irb(main):001:0> require 'json'
=> true
irb(main):002:0> a = "[\"6000208902912790\"]"
=> "[\"6000208902912790\"]"
irb(main):003:0> b = JSON.parse a
=> ["6000208902912790"]
irb(main):004:0> b
=> ["6000208902912790"]
irb(main):005:0> b.to_s
=> "[\"6000208902912790\"]"
update (as per the last edit of OP)
irb(main):002:0> a = "[\"6000208900\",\"600020890225\",\"600900231930\"]"
=> "[\"6000208900\",\"600020890225\",\"600900231930\"]"
irb(main):006:0> a.scan(/\d+/).map(&:to_i)
=> [6000208900, 600020890225, 600900231930]
irb(main):007:0>
The code a.gsub!(/^\"|\"?$/, '') can't remove the double quote characters because they are not at the beginning and the end of the string. To get what you want try this:
a.gsub(/((?<=^\[)")|("(?=\]$))/, '')
try this:
=> a = "[\"6000208902912790\"]"
=> a.chars.select{ |x| x =~ %r|\d| }.join
=> "6000208902912790"
=> [a.chars.select { |x| x =~ %r|\d| }.join]
=> ["6000208902912790"] # <= array with string
=> [a.chars.select { |x| x =~ %r|\d| }.join].to_s
=> "[\"6000208902912790\"]" # <= come back :)
a="["6000208902912790"]" will return `unexpected tINTEGER`error;
so a="[\"6000208902912790\"]"is used with \ character for double quotes.
As a solution you should try to remove double quotes that will solve the problem.
Do this
a.gsub!(/"/, '')

Replace with uppercase characters with gsub

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"

In Ruby, what is the most correct way to use Regular Expression to match a single digit and **nothing else**?

(Update: this question's main focus is to test the "nothing else" part)
Given a string s, which can contain anything, what is the most correct regexp in Ruby to check whether it is a single digit and nothing else? (a single digit and only a single digit).
Use /\A\d\z/
irb(main):001:0> "asd\n7\n" =~ /\A\d\Z/
=> nil # works as false
irb(main):002:0> "asd\n7\n" =~ /\A\d\z/
=> nil # works as false
irb(main):083:0> "7\n"=~/\A\d\Z/
=> 0 # \Z fails, need \z
irb(main):084:0> "7\n"=~/\A\d\z/
=> nil # works as false
irb(main):005:0> "7" =~ /\A\d\Z/
=> 0 # works as true
irb(main):006:0> "7" =~ /\A\d\z/
=> 0 # works as true
http://www.zenspider.com/Languages/Ruby/QuickRef.html :
\z end of a string
\Z end of a string, or before newline at the end
Try /\A\d(?![\S\W])/?
irb(main):016:0> "7" =~ /\A\d(?![\S\W])/
=> 0
irb(main):017:0> "7\n" =~ /\A\d(?![\S\W])/
=> nil
irb(main):018:0> "aljda\n7\n" =~ /\A\d(?![\S\W])/
=> nil
irb(main):022:0> "85" =~ /\A\d(?![\S\W])/
=> nil
irb(main):023:0> "b5" =~ /\A\d(?![\S\W])/
=> nil
s.scan(/\b\d\b/)
irb(main):001:0> "7\n" =~ /\b\d\z/
=> nil
irb(main):002:0> "7" =~ /\b\d\z/
=> 0
^\d$
^ is start of the string, \d is a digit and $ is the end of the string
NOTE: as stated in comments ^ and $ work for both lines and strings so if you plan to have a multi-line input you should use \A and \Z

Resources