Following is my code:
md5 = Digest::MD5.new
md5 << "!##$"
Then comes the error:
SyntaxError: (irb):46: unterminated string meets end of file
What is wrong? And how can I calculate the md5 hash of the string "!##$"?
The hash # sign in double quoted strings is used for variable and expression substitution. In this case, you are substituting the value of the global variable $" into the string, but you are not closing the string. The syntactically correct way of expressing that would be
"!##$"" # Note the extra closing quotes
However, it seems that you actually don't want to do variable substitution anyway, in which case you should always use single quoted strings:
'!##$'
Seems like you need to quote #:
> puts "!#\#$"
!##$
Your problem is the string you got is in a double apostrophe (") - so it is interpreted. And you have a hash (#) inside, so it is trying to do expression substitution. Put the string in a single apostrophe:
md5 << '!##$'
Related
how can i split a string "DESKTOP-AHDESI\Username" by slash in ruby 2.7.1p83
tmp = "DESKTOP-AHDESI\Username"
print tmp
tmp = tmp.split("\\")
print tmp
i got:
Ruby Error: NoMethodError undefined method `gsub!'
Problem
Your tmp variable is enclosed in double-quotes, and contains a backslash which is being interpreted as an escape rather than a character literal. You can see this easily by simply pasting your string into a REPL like irb:
"DESKTOP-AHDESI\Username" #=> "DESKTOP-AHDESIUsername"
You need to handle the backslash specially in both your String methods.
Solution
One way to handle this is to use Ruby's alternate quoting mechanism. For example:
%q(DESKTOP-AHDESI\Username).split '\\' #=> ["DESKTOP-AHDESI", "Username"]
This may not help you directly, though.
Wherever the value from tmp is coming from, you need to refactor the code to ensure that your String is properly escaped before you assign it to your variable, or otherwise pre-process it. String#dump won't really help much if the value you're assigning is unescaped before assignment, so you're going to have to fix this in whatever code you're using to generate or grab the string in the first place.
First of all, you are giving the wrong string. \ is the escape character when you use inside the "". So It will try to escape the next character U but this character doesn't have any Job so it will print U on the screen. Modify your string like below, it will work.
tmp = "DESKTOP-AHDESI\\Username"
p tmp
tmp = tmp.split("\\")
p tmp
Output
"DESKTOP-AHDESI\\Username"
["DESKTOP-AHDESI", "Username"]
Is there a way to convert a hash, possibly nested:
{:event=>"subscribe", :channel=>"data_channel", :parameters=>{:api_key=>"XXX", :sign=>"YYY"}}
into a string in specified format as below?
"{'event':'subscribe', 'channel':'data_channel', 'parameters': {'api_key':'XXX', 'sign':'YYY'}}"
EDIT
The format reminds JSON, but practically is not due to single quotes.
Make JSON, then fix it up:
require 'json'
hash = {:event=>"subscribe", :channel=>"data_channel",
:parameters=>{:api_key=>"XXX", :sign=>%q{Miles "Chief" O'Brien}}}
puts hash.to_json.gsub(/"((?:\\[\"]|[^\"])*)"/) { |x|
%Q{'#{$1.gsub(/'|\\"/, ?' => %q{\'}, %q{\\"} => ?")}'}
}
# => {'event':'subscribe','channel':'data_channel',
# 'parameters':{'api_key':'XXX','sign':'Miles "Chief" O\'Brien'}}
EDIT: The first regex says: match a double quote, then a sequence of either escaped double quotes/backslashes, or non-double-quote/backslash characters, then a double quote again. This makes sure we only find strings, and not accidental half-strings like "Miles \". For each such string, we surround the bit that was inside the double quotes ($1) with single quotes, and run a sub-replacement on it that will find escaped double quotes and unescaped single quotes, unescape the former and escape the latter.
Also, sorry about wonky highlighting, seems StackOverflow syntax highlighter can't deal with alternate forms of Ruby quoting, but they're so convenient when you're working with quote characters...
Your desired output looks like a JSON. Try
require 'json'
JSON.dump(hash)
=> "{\"event\":\"subscribe\",\"channel\":\"data_channel\",\"parameters\":{\"api_key\":\"XXX\",\"sign\":\"YYY\"}}"
To have single quotes you can try something like:
JSON.dump(hash).gsub('"', '\'')
It returns:
{'event':'subscribe','channel':'data_channel','parameters':{'api_key':'XXX','sign':'YYY'}}
I have this string:
str = "no,\"contact_last_name\",\"token\""
=> "no,\"contact_last_name\",\"token\""
I want to remove the escaped double quoted string character \". I use gsub:
result = str.gsub('\\"','')
=> "no,\"contact_last_name\",\"token\""
It appears that the string has not substituted the double quote escape characters in the string.
Why am I trying to do this? I have this csv file:
no,"contact_last_name","token",company,urbanization,sec-"property_address","property_address",city-state-zip,ase,oel,presorttrayid,presortdate,imbno,encodedimbno,fca,"property_city","property_state","property_zip"
1,MARIE A JEANTY,1083123,,,,17 SW 6TH AVE,DANIA BEACH FL 33004-3260,Electronic Service Requested,,T00215,12/14/2016,00-314-901373799-105112-33004-3260-17,TATTTADTATTDDDTTFDDFATFTDDDTTFADTTDFAAADDATDAATTFDTDFTTAFFTTATFFF,017,DANIA BEACH,FL, 33004-3260
When I try to open it with CSV, I get the following error:
CSV.foreach(path, headers: true) do |row|
end
CSV::MalformedCSVError: Illegal quoting in line 1.
Once I removed those double quoted strings in the first row (the header), the error went away. So I am trying to remove those double quoted strings before I run it through CSV:
file = File.open "file.csv"
contents = file.read
"no,\"contact_last_name\",\"token\" ... "
contents.gsub!('\\"','')
So again my question is why is gsub not removing the specified characters? Note that this actuall does work:
contents.gsub /"/, ""
as if the string is ignoring the \ character.
There is no escaped double quote in this string:
"no,\"contact_last_name\",\"token\""
The interpreter recognizes the text above as a string because it is enclosed in double quotes. And because of the same reason, the double quotes embedded in the string must be escaped; otherwise they signal the end of the string.
The enclosing double quote characters are part of the language, not part of the string. The use of backslash (\) as an escape character is also the language's way to put inside a string characters that otherwise have special meaning (double quotes f.e.).
The actual string stored in the str variable is:
no,"contact_last_name","token"
You can check this for yourself if you tell the interpreter to put the string on screen (puts str).
To answer the issue from the question's title, all your efforts to substitute escaped characters string were in vain just because the string doesn't contain the character sequences you tried to find and replace.
And the actual problem is that the CSV file is malformed. The 6th value on the first row (sec-"property_address") doesn't follow the format of a correctly encoded CSV file.
It should read either sec-property_address or "sec-property_address"; i.e. the value should be either not enclosed in quotes at all or completely enclosed in quotes. Having it partially enclosed in quotes confuses the Ruby's CSV parser.
The string looks fine; You're not understanding what you're seeing. Meditate on this:
"no,\"contact_last_name\",\"token\"" # => "no,\"contact_last_name\",\"token\""
'no,"contact_last_name","token"' # => "no,\"contact_last_name\",\"token\""
%q[no,"contact_last_name","token"] # => "no,\"contact_last_name\",\"token\""
%Q#no,"contact_last_name","token"# # => "no,\"contact_last_name\",\"token\""
When looking at a string that is delimited by double-quotes, it's necessary to escape certain characters, such as embedded double-quotes. Ruby, along with many other languages, has multiple ways of defining a string to remove that need.
I'm trying to do a simple string sub in Ruby.
The second argument to sub() is a long piece of minified JavaScript which has regular expressions contained in it. Back references in the regex in this string seem to be effecting the result of sub, because the replaced string (i.e., the first argument) is appearing in the output string.
Example:
input = "string <!--tooreplace--> is here"
output = input.sub("<!--tooreplace-->", "\&")
I want the output to be:
"string \& is here"
Not:
"string & is here"
or if escaping the regex
"string <!--tooreplace--> is here"
Basically, I want some way of doing a string sub that has no regex consequences at all - just a simple string replace.
To avoid having to figure out how to escape the replacement string, use Regex.escape. It's handy when replacements are complicated, or dealing with it is an unnecessary pain. A little helper on String is nice too.
input.sub("<!--toreplace-->", Regexp.escape('\&'))
You can also use block notation to make it simpler (as opposed to Regexp.escape):
=> puts input.sub("<!--tooreplace-->") {'\&'}
string \& is here
Use single quotes and escape the backslash:
output = input.sub("<!--tooreplace-->", '\\\&') #=> "string \\& is here"
Well, since '\\&' (that is, \ followed by &) is being interpreted as a special regex statement, it stands to reason that you need to escape the backslash. In fact, this works:
>> puts 'abc'.sub 'b', '\\\\&'
a\&c
Note that \\\\& represents the literal string \\&.
I am trying to construct a regex to find a string in ruby
str = "foo"
I want to be able to stop trying to find the string after it finds the closing quotation mark. I also want to keep the quotation marks so I can output the string I found as:
puts "the string is:" + str
=> the string is: "foo"
I am pretty new to using regular expressions.
Here is a start:
/".*?"/
Explanation:
" Match a literal double quote.
.*? Match any characters, as few as possible (non-greedy)
" Match a second literal double quote.
Rubular
Note that this won't work if the string contains escaped quotes or is quoted with single quotes.