Ruby: Write escaped string to YAML
If you want to store an escaped string in YAML,
escape it using #inspect
before you convert it to YAML:
irb> require 'yaml'
=> true
irb> str = %{This string's a little complicated, but it "does the job" (man, I hate scare quotes)}
=> "This string's a little complicated, but it \"does the job\" (man, I hate scare quotes)"
irb> puts str
This string's a little complicated, but it "does the job" (man, I hate scare quotes)
=> nil
irb> puts str.inspect
"This string's a little complicated, but it \"does the job\" (man, I hate scare quotes)"
=> nil
irb> puts str.to_yaml
--- This string's a little complicated, but it "does the job" (man, I hate scare quotes)
=> nil
irb> puts str.inspect.to_yaml
--- "\"This string's a little complicated, but it \\\"does the job\\\" (man, I hate scare quotes)\""
=> nil
YAML doesn't quote strings unless it has to. It quotes strings if they include things that it would miss if it stored it unquoted - like surrounding quote characters or trailing or leading spaces:
irb> puts (str + " ").to_yaml
--- "This string's a little complicated, but it \"does the job\" (man, I hate scare quotes) "
=> nil
irb> puts %{"#{str}"}.to_yaml
--- "\"This string's a little complicated, but it \"does the job\" (man, I hate scare quotes)\""
=> nil
irb> puts (" " + str).to_yaml
--- " This string's a little complicated, but it \"does the job\" (man, I hate scare quotes)"
=> nil
However, as a YAML consumer, whether the string is quoted shouldn't matter to you. You should never be parsing the YAML text yourself - leave that to the libraries. If you need the string to be quoted in the YAML file, that smells bad to me.
It doesn't matter whether your strings have '&'s in them, YAML will preserve the string:
irb> test = "I'm a b&d string"
=> "I'm a b&d string"
irb> YAML::load(YAML::dump(test))
=> "I'm a b&d string"
irb> YAML::load(YAML::dump(test)) == test
=> true
How can I escape % characters in YAML?
Try %%
it might work to escape.
how to escape a single quote (onwer's) in yaml file
If you have an actual regular expression: (shortened for brevity)
re = /owner's PID (?<tid>[\d]+)/
#=> /owner's PID (?<tid>[\d]+)/
You can get its string representation via source
:
re.source
#=> "owner's PID (?<tid>[\\d]+)"
This can be used in YAML:
require 'yaml'
yaml = { 'pattern' => re.source }.to_yaml
#=> "---\npattern: owner's PID (?<tid>[\\d]+)\n"
puts yaml
Output:
---
pattern: owner's PID (?<tid>[\d]+)
To parse it:
hash = YAML.load(yaml)
#=> {"pattern"=>"owner's PID (?<tid>[\\d]+)"}
And a regular expression can be created via:
Regexp.new(hash['pattern'])
#=> /owner's PID (?<tid>[\d]+)/
Note that Regexp#source
doesn't retain the regexp's options. You might have to store them separately via Regexp#options
.
How do I declare a string with both single and double quotes in YAML?
escaping should be done like this
"When you're using double quotes, they look like \"this\""
YAML: error parsing a string with escaped double quote
Your problem is that heredocs act like double quoted strings as far as escaping is concerned. That means that a \"
in your heredoc ends up as just "
in your string. Observe:
>> data_ =<<END_
description: "Acme acquires ILM: Lucas says \"Inevitable!\""
END_
>> puts data_
description: "Acme acquires ILM: Lucas says "Inevitable!""
You want to get a \
into the YAML string so you'll have to escape it:
data_ =<<END_
description: "Acme acquires ILM: Lucas says \\"Inevitable!\\""
END_
Alternatively, use %q{...}
to quote your string so that it behaves more like a single quoted string:
data_ = %q{
description: "Acme acquires ILM: Lucas says \"Inevitable!\""
}
Best way to escape and unescape strings in Ruby?
Ruby 2.5 added String#undump
as a complement to String#dump
:
$ irb
irb(main):001:0> dumped_newline = "\n".dump
=> "\"\\n\""
irb(main):002:0> undumped_newline = dumped_newline.undump
=> "\n"
With it:
def escape(s)
s.dump[1..-2]
end
def unescape(s)
"\"#{s}\"".undump
end
$irb
irb(main):001:0> escape("\n \" \\")
=> "\\n \\\" \\\\"
irb(main):002:0> unescape("\\n \\\" \\\\")
=> "\n \" \\"
Ruby to_yaml utf8 string
This is probably a really bad idea as I'm sure YAML has its reasons for encoding the characters as it does, but it doesn't seem too hard to undo:
require 'yaml'
require 'yaml/encoding'
text = "Ça va bien?"
puts text.to_yaml(:Encoding => :Utf8) # => --- "\xC3\x87a va bien?"
puts YAML.unescape(YAML.dump(text)) # => --- "Ça va bien?"
Related Topics
How to View a Sample of the Call Stack in Ruby
Rake Assets:Precompile Gets Killed When There Is a Console Session Open in Production
Using Gets() Gives "No Such File or Directory" Error When I Pass Arguments to My Script
Heroku: How to Push Seeds.Rb to Existing Rails App
Adding Keywords to Ruby Syntax Highlighting for Notepad++
I'm Getting "Found Character That Cannot Start Any Token While Scanning for the Next Token"
Ruby: How to "Require" a File from the Current Working Dir
Convert Array to Hash While Preserving Array Index Values in Ruby
Rails Check_Box_Tag How to Pass Value When Checked Ajaxily
Print All Method Names of a Class in Ruby
Rspec Stubbing Method for Only Specific Arguments
How to Validate the Presence of a Belongs to Association with Rails
What Does the Underscore Mean in Literal Numbers
Resetting a Singleton Instance in Ruby
Rails 3: Call Functions Inside Controllers
Strong Parameters Require Multiple