Nathan
Nathan

Reputation: 12304

Parsing string literals from a file in ruby

I am reading a string from a file in ruby. This string has escape sequences in them that I would like turned into the appropriate characters.

For example I might have a string like this:

"this is a string\n"

With the actual characters \ and n in the file, not the newline character.

Is there a built in function to decode these literals? Or will I have to write something to do it manually?

Note that I'm not using rails, and the file data is not json.

Upvotes: 1

Views: 639

Answers (4)

Paulo Fidalgo
Paulo Fidalgo

Reputation: 22296

You can use %q{} %q{"this is a string\n"} => "\"this is a string\n\""

This way it will escape the string characters.

From the documentation:

There’s a general delimited string and regex quoting syntax similar to Perl’s. It looks like %q{this} (single-quoted), or %Q{this} (double-quoted), and %w{this for a single-quoted list of words}. You %Q|can| %Q(use) %Q^other^ delimiters if you like.

EDIT: Since I misunderstand the question, I think your best option, if you do not want to rely on third-party libs (like JSON), is to replace with proper values:

str.gsub(/(\n)+/,"\n")

Upvotes: 0

SirDarius
SirDarius

Reputation: 42899

If you are satisfied with the escape sequences supported by the JSON format, you can do something like this:

require 'json'

def unescape(str)
  JSON.parse("[\"#{str}\"]")[0]
end

p unescape("\\nline\\u0040")          # "\nline@"

Please note that the ruby JSON parser does not accept naked values, so the string needs to be wrapped in an array or an object.

The JSON parser will also raise errors if the string cannot be correctly parsed so you should add some error handling code.

Upvotes: 2

Ajedi32
Ajedi32

Reputation: 48368

If this is just a plain text file (e.g. not JSON, YAML, or another data format that has specific escape sequences) then those character sequences have no special meaning. Therefore, if you want to give them one in the context of your application you'll have to write the code to do that yourself. For newlines specifically, you could do something like this:

input.gsub!('\n', "\n")

Upvotes: 1

Cristian Lupascu
Cristian Lupascu

Reputation: 40536

I hope there's a better option, but it's good to know that you can achieve this with Kernel#eval:

literal_from_file = '"this is a string\n"'

puts literal_from_file       # print the literal first
puts eval(literal_from_file) # and then print the interpreted string

will print:

"this is a string\n"
this is a string

Upvotes: 0

Related Questions