Weird backslash substitution in Ruby
This is an issue because backslash (\) serves as an escape character for Regexps and Strings. You could do use the special variable \& to reduce the number backslashes in the gsub replacement string.
foo.gsub(/\\/,'\&\&\&') #for some string foo replace each \ with \\\
EDIT: I should mention that the value of \& is from a Regexp match, in this case a single backslash.
Also, I thought that there was a special way to create a string that disabled the escape character, but apparently not. None of these will produce two slashes:
puts "\\"
puts '\\'
puts %q{\\}
puts %Q{\\}
puts """\\"""
puts '''\\'''
puts <<EOF
\\
EOF
How to perform String replacements without backslash escaping in Ruby
Eventually I found pretty simple solution:
input = '{"regex": "/^\\\\([0-3][0-9]\\\\)$/"}'
puts input # gives => {"regex": "/^\\([0-3][0-9]\\)$/"}
search = '/^\\\\([0-3][0-9]\\\\)$/'
replace = '/^\\\\([0-9]\\\\)$/'
puts input.sub(search, replace) # gives => {"regex": "/^\([0-9]\)$/"}, which is wrong result
input[search] = replace # <-- here is the trick, but makes changes in place
puts input # gives => {"regex": "/^\\([0-9]\\)$/"} => success!
But! If your string doesn't contain any search
substring you will get an string not matched (IndexError)
.
So you may want to bulletproof your code like this:
input[search] = replace if input.include? search
Also, if you want to keep your input
untouched you may .dup
it to another variable:
new_input = input.dup
new_input[search] = replace if new_input.include? search
backslash at end of string causes error when inserting into InfluxDB
You just use parameterized query strings:
INSERT INTO my_db.default.my_measurement,my_tag=1 my_val=%{1}
Where when you call it you do this:
influxdb.query("...query...", params: [ string ])
What you did was create a classic injection bug by sending unescaped data into a query. The same principle applies in any database with a plain-text string representation, or even other data formats like HTML and JavaScript.
What's the point of escaping a single backslash in single quotes in Ruby?
backslashes are an escape character so if you were to write '\'
would think you were trying to escape the '
.
Otherwise if it treated single character strings differentls you wanted to write '
you would have to use double quotes, which will quickly get harder to maintain when you need to remember which quotes to use when.
Gsub causing part of string to be substituted
It happens because "\\'"
has a special meaning when it occurs as the replacement argument of gsub
, namely it means the post-match substring.
To do what you want, you can use a block:
a.gsub("'"){"\\'"}
# => "abc \\'def\\' ghi"
Notice that the backslash is escaped in the string inspection, so it appears as \\
.
How come you can't gsub this string in Ruby?
You are falling into the trap of a different meaning of escapes when used in strings with double quotes vs single quotes. Double-quoted strings allow escape characters to be used. Thus, here "\n"
actually is a one-character string containing a single line feed. Compare that to '\n'
which is a two-character string containing a literal backslash followed by a character n.
This explains, whey your gsub
doesn't match. If you use the following code, it should work:
"\\n".gsub('\n','\b')
For your actual issue, you can use this
string = "R3pQvDqmz/EQ7zho2mhIeE6UB4dLa6GUH7173VEMdGCcdsRm5pernkqCgbnj\\nZjTX\\n"
new_string = string.gsub("\\n", "\n")
Replace & to \& in Ruby seems impossible?
Your linked question provides a solution - use the block form of gsub
:
irb(main):009:0> puts "asdf & asdf".gsub("&"){'\&'}
asdf \& asdf
How to replace & with \& with gsub on rails?
Use triple \
in the replacement string:
print 'Company & Co. KG'.gsub('&', '\\\&')
# Company \& Co. KG=> nil
You can check that a single backslash is added by checking the length of both strings:
'Company & Co. KG'.size
# => 16
'Company & Co. KG'.gsub('&', '\\\&').size
# => 17
To understand it better, read about escaping:
- https://en.wikibooks.org/wiki/Ruby_Programming/Strings#Single_quotes
- https://gist.github.com/kbaribeau/1103102
- Weird backslash substitution in Ruby
EDIT:
\&
is a backreference to the whole match (like \0
)
'Company & Co. KG'.gsub(/Co/, '-\&-')
# => "-Co-mpany & -Co-. KG"
'Company & Co. KG'.gsub(/Co/, '-\0-')
# => "-Co-mpany & -Co-. KG"
Ruby double slash gsub issue
The following works for me. Have you tried it in the terminal? It could be unescaped when you output the result.
> a = "<<<patent-inv>>>"
> a.gsub("<<<patent-inv>>>", "part1\\\\part2")
=> "part1\\part2"
You can see how the output varies between puts
and p
> puts a
part1\part2
> p a
"part1\\part2"
> puts a.inspect
"part1\\part2"
EDIT Here is the output displayed as you want it.
1.9.2-p290 :037 > a.gsub!("<<<patent-inv>>>", "part1\\\\\\part2")
=> "part1\\\\part2"
> p a
"part1\\\\part2"
=> "part1\\\\part2"
> puts a
part1\\part2
=> nil
We know that 4 backslashes when changed equals 2 backslashes when unescaped. So 4 backslashes need to be generated AFTER the substitution for it to be displayed correctly.
Non-regexp version of gsub in Ruby
There are two layers of escaping for the second parameter of gsub:
The first layer is Ruby string constant. If it is written like \\\\\\
it is unescaped by Ruby like \\\
the second layer is gsub itself: \\\
is treated like \\
+ \
double backslash is resolved into single: \\
=> \
and the single trailing backslash at the end is resolved as itself.
8 backslashes are parsed in the similar way:
"\\\\\\\\" => "\\\\"
and then
"\\\\" => "\\"
so the constants consisting of six and eight backslashes are resolved into two backslashes.
To make life a bit easier, a block may be used in gsub function. String constants in a block are passed only through Ruby layer (thanks to @Sorrow).
"foo\\bar".gsub("\\") {"\\\\"}
Related Topics
Difference Between "Or" and || in Ruby
How to Pass Command Line Arguments to a Rake Task
Does Ruby Have Real Multithreading
Difference Between Rake Db:Migrate Db:Reset and Db:Schema:Load
How to Modify Path For Homebrew
How to Get Source Code of a Method Dynamically and Also Which File Is This Method Locate In
Ruby Operator Precedence Table
How to Redirect to a 404 in Rails
How to Track System-Specific Config Files in a Repo/Project
What's the Difference Between Ruby'S Dup and Clone Methods
Look Up All Descendants of a Class in Ruby
Why Is This Rmagick Call Generating a Segmentation Fault
Open an Io Stream from a Local File or Url
How to Dynamically Create a Local Variable
Understanding the "||" or Operator in If Conditionals in Ruby