Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have a password that contains "\y". I get:
"a\yb" # => "ayb"
'a\yb' # => 'a\\yb'
"a\\yb" # => "a\\yb"
'a\\b' # => "a\\yb"
And nothing (like concatenation or sub) works.
Is there a way to not change the password?
When you say:
'a\yb'
Then you get this back:
"a\\yb"
These are identical as far as Ruby is concerned. Inside of double quotes (") the backslash has special meaning. A single backslash is used to indicate either control codes like \n meaning newline, or literal versions of same, like \\ meaning literal backslash.
Try this:
puts "a\\yb"
Then you'll see exactly what you want. The \\ part is just escaping.
When you use p you're calling:
puts "a\\yb".inspect
This inspect part puts it back into a double-quoted and escaped string, which is where you're getting confused. Print the string, not the "inspected" version of it.
Works for me. Can you show us some context?
ruby -v
#=> ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
ruby -e 'puts "a\\yb"'
#=> a\yb
After your edits, the problem is using p instead of puts. For instance:
ruby -e 'puts "a\\yb"'
#=> a\yb
ruby -e 'p "a\\yb"'
#=> "a\\yb"
See this discussion.
In simple words p print obj.inspect to output
Simple way to see this:
irb(main):009:0> string = %q{a\yb}
=> "a\\yb"
irb(main):018:0> puts string.inspect
"a\\yb"
irb(main):019:0> p string
"a\\yb"
irb(main):010:0> puts string
a\yb
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I tried string interpolation with single quotes using #{} but it does not work. When I tried it with double quotes it works. Please explain to me why this is so, if it's possible to do string interpolation with single quotes and how to do so in ruby if it is possible.
Ruby doesn't interpret single-quoted strings.
This might seem like a limitation at first, but it's actually a nice feature. It allows you to enter many characters without having to escape them, which results in more legible code:
file = 'C:\foo\bar\baz.txt'
# as opposed to:
file = "C:\\foo\\bar\\baz.txt"
Or when having a string about string interpolation itself: (note that Stack Overflow's syntax highlighting is misleading – there's no interpolation)
string = 'In Ruby, you can write "1 + 2 = #{ 1 + 2 }" to get "1 + 2 = 3".'
# instead of:
string = "In Ruby, you can write \"1 + 2 = \#{ 1 + 2 }\" to get \"1 + 2 = 3\"."
Apart from '...' and "...", Ruby also has %q(...) and %Q(...) style string literals (the former without, the latter with interpolation). This is especially useful if your string contains both, single and double quotes:
string = %q(A string containing '...' and "...")
You can even pick your own delimiter: (again, the syntax highlighter can't keep up)
string = %q#A string containing '...', "..." and (...)"#
And finally, you can mix and match different string literal styles:
string = %q(foo) 'bar' "baz"
#=> "foobarbaz"
This is how ruby language is designed.
From language docs: Literals
Double-quote strings allow escaped characters such as \n for newline,
\t for tab, etc.
Double-quote strings allow interpolation of other
values using #{...}:
value = 10
puts "Test value is #{value}"
# => Test value is 10
Interpolation may be disabled by escaping the “#” character or using single-quote strings
puts 'Test value is #{value}'
# => Test value is #{value}
Single-Quoted Strings and Escapes/Expressions
That's just how the language is defined: you can't interpolate using the embedded expression operator (#{}) within a single-quoted string. Unlike double-quoted strings, single-quoted strings aren't scanned for embedded expressions or most escapes. This is important when you need to do things like printing escape characters or unevaluated expressions such as:
puts 'This is a newline character: \n'
puts 'This is how you embed an expression: #{foo}'
That doesn't mean you can't approximate interpolation with single-quoted strings in other ways. For example:
'foo: %s' % 'bar'
#=> "foo: bar"
sprintf '%d, %d, %d', 1, 2, 3
#=> "1, 2, 3"
This question already has answers here:
Best way to escape and unescape strings in Ruby?
(7 answers)
Closed 5 years ago.
How to convert a string with special characters escaped to the actual special chars?
For example, if I have this:
s = "hello\\nworld"
The output of puts is naturally this:
> puts s
hello\nworld
But how do I transform it into this?
hello
world
In other words, is there any function to unescape backslashed characters?
Your best bet is to do some string replacements.
s = "hello\\nworld"
puts s.gsub("\\n", "\n")
# >> hello
# >> world
The downside of this approach is that you have to explicitly list/process all special chars you need to unescape.
You interpolate \ by \\ ,
use one backslash instead of two:
s = "hello\nworld"
puts s
#=> hello
world
If your string is from a trusted source, you can use eval:
s = "hello\\nworld"
eval("\"#{s}\"") # => "hello\nworld"
Note that this allows arbitrary code execution:
s = "\"; loop { }; \""
eval("\"#{s}\"") # => infinite loop
Also this doesn't work for input like s = "\"".
This question already has answers here:
Why do two strings separated by space concatenate in Ruby?
(2 answers)
Closed 8 years ago.
How the following line of code concatenates a string in ruby?
2.1.0 :052 > value = "Kamesh" "Waran"
=> "KameshWaran"
I understand that '+' is a method on String class which concatenates the strings passed. How the space(' ') can be the operator/method?
Can anyone elaborate how the space(' ') concatenate strings?
The space is not an operator. This only works for string literals, and is just part of the literal syntax, like the double-quotes. If you have two string literals with nothing but whitespace between them, they get turned into a single string. It's a convention borrowed from later versions of C.
irb(main):001:0> foobar = "foo" "bar"
=> "foobar"
irb(main):002:0> foo="foo"
=> "foo"
irb(main):003:0> bar="bar"
=> "bar"
irb(main):004:0> foo bar
NoMethodError: undefined method `foo' for main:Object
from (irb):4
from /usr/local/var/rbenv/versions/2.1.3/bin/irb:11:in `<main>'
irb(main):005:0>
If you do a search on this site you get an answer.
Found on :
Why do two strings separated by space concatenate in Ruby?
Implementation details can be found in parse.y file in Ruby source
code. Specifically, here.
A Ruby string is either a tCHAR (e.g. ?q), a string1 (e.g. "q", 'q',
or %q{q}), or a recursive definition of the concatenation of string1
and string itself, which results in string expressions like "foo"
"bar", 'foo' "bar" or ?f "oo" 'bar' being concatenated.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm trying to output
[fish] \"aquatic animal\"\n
But the closest I came is:
[fish]\aquatic animal
#entries.each do |key,value|
puts "["+key+"]" +"\\"+value+"\n"
end
#entries = {"zebra"=>"African land animal with stripes", "fish"=>"aquatic animal", "apple"=>"fruit"}
TL;DR
You can make this really short and easy to read using Ruby's sprintf and its handy partner %:
#entries = {"zebra"=>"African land animal with stripes", "fish"=>"aquatic animal", "apple"=>"fruit"}
template = '[%s] \"%s\"\n'
#entries.each do |key_and_value|
puts template % key_and_value
end
# => [zebra] \"African land animal with stripes\"\n
# [fish] \"aquatic animal\"\n
# [apple] \"fruit\"\n
What you need to know is that inside double quotes, backslashes have special meaning. For example, in "foo\nbar", \n is transformed into a newline:
puts "foo\nbar"
# => foo
# bar
In order to use a literal backslash inside double quotes, it must be preceded by a backslash, which "escapes" it:
puts "foo\\nbar"
# => foo\nbar
To use double quotes inside double quotes, you need to escape them in the same way:
puts "I have "inner" quotes"
# => SyntaxError: unexpected tIDENTIFIER, expecting end-of-input
# puts "I have "inner" quotes"
# ^
puts "I have \"inner\" quotes"
# => I have "inner" quotes
If we wanted to print [fish] \"aquatic animal\"\n, we'd have to do this:
puts "[fish] \\\"aquatic animal\\\"\\n"
# => [fish] \"aquatic animal\"\n
We replaced each \ with \\ and each " with \", which looks pretty messy. On thing that will help is using Ruby's alternative "percent sign" syntax:
puts %{[fish] \\"aquatic animal\\"\\n}
# => [fish] \"aquatic animal\"\n
We still have to replace \ with \\, because backslashes still need to be escaped using this syntax, but double quotes don't need to be escaped, so it's a little nicer. Putting it together, we get this:
puts %{[#{key}] \\"#{value}\\"\\n}
That's not bad, but it's still not especially easy to read. Another option is using sprintf, which lets us define a "template" string and then substitute values into it later on. Since we don't need interpolation (#{...}), we can use single quotes instead, which means we can use backslashes and double quotes inside it without escaping them:
template = '[%s] \"%s\"\n'
str = sprintf(template, "fish", "aquatic animal")
puts str
# => [fish] \"aquatic animal\"\n
As you can see, each %s in the "template" is replaced by one of the arguments to sprintf. Ruby also has a special shortcut for sprintf, which is the % operator:
str = template % [ "fish", "aquatic animal" ]
puts str
# => [fish] \"aquatic animal\"\n
We can combine this with your loop for an especially clean solution:
#entries = {"zebra"=>"African land animal with stripes", "fish"=>"aquatic animal", "apple"=>"fruit"}
template = '[%s] \"%s\"\n'
#entries.each do |key_and_value|
puts template % key_and_value
end
# => [zebra] \"African land animal with stripes\"\n
# [fish] \"aquatic animal\"\n
# [apple] \"fruit\"\n
Try
puts "["+key+"]" +" "+ "\\\""+value+"\\\"\\n"
I'm reading some Ruby code and I don't understand this snippet:
thing = '${other-thing}/etc/'
It appears to substitute a value for the ${other-thing} and use that to build the String thing but I haven't been able to recreate this myself.
EDIT: Sorry to all, it turns out there was some preprocessing going on by Maven (a Java build tool). The accepted answer shows how one could do the substitution in straight Ruby.
$ irb
irb(main):001:0> a = "Hello"
=> "Hello"
irb(main):002:0> b = "world"
=> "world"
irb(main):003:0> puts "${a}, ${b}!" # Doesn't work.
${a}, ${b}!
=> nil
irb(main):004:0> puts "#{a}, #{b}!" # Works fine.
Hello, world!
=> nil
irb(main):005:0> puts '#{a}, #{b}!' # Doesn't work.
#{a}, #{b}!
=> nil
You wanted #{...}, not ${...} I believe. Also, you don't get substitutions inside of single-quoted strings, only double-quoted (or equivalents – there's dozens of ways to delimit strings in Ruby).