Ruby: How to remove trailing backslashes from a string? - ruby-on-rails

I have a string like
"car\"
which I will be storing in postgres db. I want to remove the backslash from the string before saving. Is there a way I can do that in ruby or in postgres? When I try to remove it in ruby, it considers the quote after the backslash as an escape character.

See following code:
1.9.3p125 :022 > s = "cat\\"
=> "cat\\"
1.9.3p125 :023 > puts s
cat\
=> nil
1.9.3p125 :024 > s.chomp("\\")
=> "cat"
1.9.3p125 :025 >

People don't do this much, but Ruby's String class supports:
irb(main):002:0> str = 'car\\'
=> "car\\"
irb(main):003:0> str[/\\$/] = ''
=> ""
irb(main):004:0> str
=> "car"
It's a conditional search for a trailing '\', and replacement with an empty string.

To remove a trailing backslash:
"car\\".gsub!(/\\$/, "")
Note that the backslash has to be escaped itself with a backslash.

puts '"car\"'.gsub(/\\(")?$/, '\1')
that will do it,
but, is the trailing slash always at the en followed by a quote?

See what says the
str.dump
operation, and then try to operate on that.

Related

Ruby gsub not replacing newline character

I have this code
str = #universal_claim_form.errors.full_messages.join
str.gsub('Patient Contact Information: Value', 'Patient phone number') if str =~ /Patient Contact Information/
debugger
str.gsub("\\n", "<br/>")
debugger
flash.now[:error] = "Form has errors and was unable to be submitted.<br/> " << str
the first gsub replaces an unwanted message and the second gsub it meant to replace all the newline characters with html line breaks
at the first debugger line str = "PMP Validation failed. This happens when something you entered does not pass PMP specific validations.\\nPatient phone number: Value must be a 10 digit number"
and at the second debugger the line hasn't changed
what's even more weird is that I did this in irb at the command line and it worked
2.1.1 :001 > s = 'test'
=> "test"
2.1.1 :002 > s
=> "test"
2.1.1 :003 > s += '\ntest'
=> "test\\ntest"
2.1.1 :004 > s.gsub('\\n', '<br/>')
=> "test<br/>test"
2.1.1 :005 >
You can call gsub! to mutate the string you are calling it on (instead of returning a new string).
The reason gsub "works" in irb is because it is outputting the result - irb does not do any assignment or mutation (beyond what one enters), e.g.
irb(main):001:0> foo = 4
=> 4
irb(main):002:0> foo + 6
=> 10
foo is getting assigned 4 so it outputs the result of that assignment, likewise with foo + 6 it outputs the result but the value of foo is unchanged.
When you call gsub it returns a new string with the substitution(s), this is why you feel it "works" in irb (this is no different then it printing "4" above).

How to convert a string ("€ 289,95") to a float ("289.95") in Rails?

Context
I have Rails (4.0.1 + Ruby 2.0.0) connected to a PostgreSQL database filled with strings like "€ 289,95". The values have been scraped from a website using Nokogiri. I want to convert the strings to floating points.
What I've tried
Rails console:
listing = Listing.find(1)
=> #<Listing id: 1, title: #, subtitle: #, name: #, price: "€ 289,95", url: #, created_at: #, updated_at: #>
listing_price = listing.price
=> "€ 289,95"
listing_price_1 = listing_price.gsub(/,/, ".")
=> "€ 289.95"
listing_price_2 = listing_price_1.gsub(/€\s/, "")
=> "€ 289.95"
listing_price_3 = listing_price_2.to_f
=> 0.0
Problem
The code works in irb but doesn't work in the rails console.
What I want to know
How to convert a string "€ 289,95" to a float "289.95" in Rails?
The step where your technique is failing is when trying to strip away € and the space from € 289.95 with the regexp /€\s/, but this is not matching, leaving the string unchanged.
The space character in € 289,95 is probably a non-breaking space (U+00A0) rather than a “normal” space, and would be used in the web page so that the € and the value are not separated.
In Ruby the non-breaking space is not matched by \s in a regexp, so your call to gsub doesn’t replace anything:
2.0.0p353 :001 > s = "€\u00a0289.95"
=> "€ 289.95"
2.0.0p353 :002 > s.gsub(/€\s/, "")
=> "€ 289.95"
Non-breaking space is matched by the POSIX bracket expression [[:space:]], or by the character property \{Blank}:
2.0.0p353 :003 > s.gsub /€[[:space:]]/, ""
=> "289.95"
2.0.0p353 :004 > s.gsub /€\p{Blank}/, ""
=> "289.95"
So if you wanted a more specific regexp than in the other answer you could use one of these.
"€ 289,95".sub(/\A\D+/, "").sub(",", ".").to_f
# => 289.95
listing.price.delete('€ ') # => "289,95"
listing.price.delete('€ ').tr(',', '.') # => "289.95"
listing.price.delete('€ ').tr(',', '.').to_f # => 289.95
String's 'delete' method is good for removing all occurrences of the target strings.
and 'tr' method takes a string of characters to search for, and a string of characters used to replace them.
Better probably than the accepted answer is:
"€ 289,95"[/[\d,.]+/].tr ',', '.'

escape double quotes in ruby

How can I replace double-quotes to &quote; in a string?
This is what I have tried:
1.9.3-p362 :009 > a = "\"That's it\", she said."
=> "\"That's it\", she said."
1.9.3-p362 :010 > a.tr('"', "&quote;")
=> "&That's it&, she said."
As you see instead of &quotes; I only get &, any idea?
use gsub instead
a.gsub(/\"/, "&quote;")
# without regex as noted by hirolau
a.gsub("\"", "&quote;")
# => "&quote;That's it&quote;, she said."

Simple regex check failing in a rails model

I have a check of the following type
validates :callback_handle, :format => { :with => /[_0-9a-zA-Z]+/ix }, :unless => "callback.nil?"
I do not want any non 0-9, a-z A-Z characters to pass. So i set callback_handle to
"!alksjda" (note ! at the begining).
This test does not fail. What am I doing wrong?
I tried a few things on irb: This is what I got:
1.9.2-p320 :001 > a = "!askldjlad"
=> "!askldjlad"
1.9.2-p320 :002 > a =~ /[_0-9a-zA-Z]+/ix
=> 1
1.9.2-p320 :003 > a = "askldjlad"
=> "askldjlad"
1.9.2-p320 :004 > a =~ /[_0-9a-zA-Z]+/ix
=> 0
I thought it would return false or nil on failure to find the match.
Can someone tell me what is wrong here in my understanding?
EDIT:
I figured out that =~ will return position of a match.
So the question becomes How do I not allow something that has any other character to not match?
Your regular expression is still able to match, because there is at least 1 character in your string that is alpha-numeric. If you want to make sure that the entire string matches then you should define the beginning and end of the match.
Old:
a =~ /[_0-9a-zA-Z]+/ix
This is saying "match at least one of these characters somewhere in a.
New:
a =~ /\A[_0-9a-zA-Z]+\z/ix
This is saying "start at the beginning of the string, then match at least 1 of only these characters, followed by the end of the string" in a.
Your regex just asks that your string contains 1 or more valid characters ... this should fix it :
validates :callback_handle, :format => { :with => /^[_0-9a-zA-Z]+$/ix }, :unless => "callback.nil?"

Rails / Ruby not following Rublar on regular expression

I have the following expression that I have tested in Rubular and that successfully matches against a snippet of HTML:
Official Website<\/h3>\s*<p><a href="([^"]*)"
However, when I run the expression in Ruby, using the following code, it returns no matches. I've reduced it down to "Official\s*Website" and it matches that, but nothing further.
Are there any additional options I need to set, or anything else that I need to do to configure Ruby/Rails to start tracking Rubular?
matches = sidebar.match(/Official\s*Website<\/h3>\s*<p><a href="([^"]*)"/)
if matches.nil?
puts "no matches"
else
puts "matches"
end
This is the relevant part of the snippet I'm matching against:
<h3>Official Website</h3><p>website.com</p>
your regular expression is correct. rubular should be working the same way your code does.
i tested it against ruby 1.8.7 and 1.9.3
irb(main):006:0> sidebar = ' <h3>Official Website</h3><p>website.com</p>'
=> " <h3>Official Website</h3><p>website.com</p>"
irb(main):007:0> sidebar.match(/Official\s*Website<\/h3>\s*<p><a href="([^"]*)"/)
=> #<MatchData "Official Website</h3><p><a href=\"http://website.com\"" 1:"http://website.com">
-
1.9.3p0 :005 > sidebar = ' <h3>Official Website</h3><p>website.com</p>'
=> " <h3>Official Website</h3><p>website.com</p>"
1.9.3p0 :006 > sidebar.match(/Official\s*Website<\/h3>\s*<p><a href="([^"]*)"/)
=> #<MatchData "Official Website</h3><p><a href=\"http://website.com\"" 1:"http://website.com">
if you want to quickly check why stuff is not working, you should try it in IRB or in your rails console. most of the times it's typo or bad encoding.

Resources