Errors in parsing escaped double quotes with json parsers - ruby

How would one parse a JSON string like this:
"[{\"something\": \"information \"YES\"\", \"next\": \"normal\"}]"
I've used both the json gem and the Oj gem but they both run into errors. I've also tried using eval() on it.
I've also tried using different regexes to target the quotes surrounding YES and replacing them with single quotes but I haven't been successful in figuring one out.

The string you posted isn't valid JSON. This would be the non-stringified JSON:
[{"something":"information \"YES\"","next":"normal"}]
Note that the escaping is still present in the value for something.
If you had this JSON as a string, the double-quote escaping depends on the language you're working in. In Ruby, this is what it looks like:
"[{\"something\":\"information \\\"YES\\\"\",\"next\":\"normal\"}]"
If you use that, you'll be able to parse it just fine:
JSON.parse("[{\"something\":\"information \\\"YES\\\"\",\"next\":\"normal\"}]")
#=> [{"something"=>"information \"YES\"", "next"=>"normal"}]

Related

YAML mapping values are not allowed

I have the following data. Which is not valid in YAML. Double quotes are not working here:
data:"{\gateway\: \172.16.16.1/24\ \modulesModel\: [\N9K-X9364v\ \N9K-vSUP\]}"
Is there any better way to format it?
You are starting escape sequences with the backslash.
Use \\ to represent the backslash in a yaml string.
However your string looks like JSON where " are replaced with \ and , are missing completely. Maybe somebody told you to Escape the " with \. This is done this way:
data: "{\"gateway\": \"172.16.16.1/24\", \"modulesModel\": [\"N9K-X9364v\" \"N9K-vSUP\"]}"

How to obtain basename in ruby from the given file path in unix or windows format?

I need to parse a basename in ruby a from file path which I get as input. Unix format works fine on Linux.
File.basename("/tmp/text.txt")
return "text.txt".
However, when I get input in windows format:
File.basename("C:\Users\john\note.txt")
or
File.basename("C:\\Users\\john\\note.txt")
"C:Usersjohn\note.txt" is the output (note that \n is a new line there), but I didn't get "note.txt".
Is there some nice solution in ruby/rails?
Solution:
"C:\\test\\note.txt".split(/\\|\//).last
=> "note.txt"
"/tmp/test/note.txt".split(/\\|\//).last
=> "note.txt"
If the Linux file name doesn't contain \, it will work.
Try pathname:
require 'pathname'
Pathname.new('C:\Users\john\note.txt').basename
# => #<Pathname:note.txt>
Pathname docs
Ref How to get filename without extension from file path in Ruby
I'm not convinced that you have a problem with your code. I think you have a problem with your test.
Ruby also uses the backslash character for escape sequences in strings, so when you type the String literal "C:\Users\john\note.txt", Ruby sees the first two backslashes as invalid escape sequences, and so ignores the escape character. \n refers to a newline. So, to Ruby, this literal is the same as "C:Usersjohn\note.txt". There aren't any file separators in that sequence, since \n is a newline, not a backslash followed by the letter n, so File.basename just returns it as it receives it.
If you ask for user input in either a graphical user interface (GUI) or command line interface (CLI), the user entering input needn't worry about Ruby String escape sequences; those only matter for String literals directly in the code. Try it! Type gets into IRB or Pry, and type or copy a file path, and press Enter, and see how Ruby displays it as a String literal.
On Windows, Ruby accepts paths given using both "/" (File::SEPARATOR) and "\\" (File::ALT_SEPARATOR), so you don't need to worry about conversion unless you are displaying it to the user.
Backslashes, while how Windows expresses things, are just a giant nuisance. Within a double-quoted string they have special meaning so you either need to do:
File.basename("C:\\Users\\john\\note.txt")
Or use single quotes that avoid the issue:
File.basename('C:\Users\john\note.txt')
Or use regular slashes which aren't impacted:
File.basename("C:/Users/john/note.txt")
Where Ruby does the mapping for you to the platform-specific path separator.

Freemarker ruby script template issue

So I am trying to run a ruby script and I have string expansion sections that are being mistaken for freemarker expressions, for example:
puts "Foo bar baz quux #{#awesome}"
In ruby the #{} is valid ruby, and I need Freemarker to ignore it. According to the documentation, I can escape lie this:
#\{#awesome}
But that leaves the backslash in the final output. I tried to do this:
#{r"#{#awesome"}}
But I get an exception saying that a number was expected... According to the docs, this should produce a literal '#{#awesome}'
What gives? Am I doing something wrong?
This will work:
${r"#{#awesome"}}
Your attempt gives error because FreeMarker's #{...} only accepts numbers.

How can I escape filenames in ruby (osx) for open/read/hexdigest?

I'm trying to catalog a bunch of files on OSX using ruby, essentially doing this:
hash = Digest::SHA1.hexdigest(File.open(fullpath).read)
This is failing on filenames that contain apostrophes, which are legal characters for a filename.
The File.open works, but I get an "Errno::EINVAL: Invalid argument" error from the read. The filenames are coming directly out of a Dir[] glob.
I've tried escaping them with backslashes, but that doesn't seem to work.
What's the right way to escape these filenames?

Ruby Typhoeus Request: url with quotes

I'm having a problem doing a request using Typhoeus as my query needs to have quotation marks into it.
If the URl is
url = "http://app.com/method.json?'my_query'"
everything works fine. However, the method I'm trying to run only returns the results I want if the query is the following (i've tested it in browser):
url2 = "http://app.com/method.json?"my_query""
When running
Typhoeus::Request.get(url2)
I get (URI::InvalidURIError)
Escaping quotes with "\" does not work. How can I do this?
Thanks
You should be properly encoding your URI with URI.encode or CGI.escape, doing so will get you proper URLs like this:
http://app.com/method.json?%27my_query%27 # Single quotes
http://app.com/method.json?%22my_query%22 # Double quotes
Try:
require 'uri'
URI.encode('"foo"')
=> "%22foo%22"
Passing json, quotes etc in GET request is tricky. In Ruby 2+ we can use Ruby's URI module's 'escape' method.
> URI.escape('http://app.com/method.json?agent={"account":
{"homePage":"http://demo.my.com","name":"Senior Leadership"}}')
But I suggest use it as POST request and pass it as a message body.

Resources