Escape double and single backslashes in a string in Ruby - ruby-on-rails

I'm trying to access a network path in my ruby script on a windows platform in a format like this.
\\servername\some windows share\folder 1\folder2\
Now If I try to use this as a path, it won't work. Single backslashes are not properly escaped for this script.
path = "\\servername\some windows share\folder 1\folder2\"
d = Dir.new(path)
I tried everything I could think of to properly escape slashes in the path. However I can't escape that single backslash - because of it's special meaning. I tried single quotes, double quotes, escaping backslash itself, using alternate quotes such as %Q{} or %q{}, using ascii to char conversion. Nothing works in a sense that I'm not doing it right. :-) Right now the temp solution is to Map a network drive N:\ pointing to that path and access it that way, but that not a solution.
Does anyone have any idea how to properly escape single backslashes?
Thank you

Just double-up every backslash, like so:
"\\\\servername\\some windows share\\folder 1\\folder2\\"

Try this
puts '\\\\servername\some windows share\folder 1\folder2\\'
#=> \\servername\some windows share\folder 1\folder2\
So long as you're using single quotes to define your string(e.g., 'foo'), a single \ does not need to be escaped. except in the following two cases
\\ works itself out to a single \. So, \\\\ will give you the starting \\ you need.
The trailing \ at the end of your path will tries to escape the closing quote so you need a \\ there as well.
Alternatively,
You could define an elegant helper for yourself. Instead of using the clunky \ path separators, you could use / in conjunction with a method like this:
def windows_path(foo)
foo.gsub('/', '\\')
end
puts windows_path '//servername/some windows share/folder 1/folder2/'
#=> \\servername\some windows share\folder 1\folder2\
Sweet!

Related

Escaping regex in a Ruby awk system command

The following works directly in my Mac OS X terminal, creating a file with a few lines:
awk '!/^1499\||^1598\||^1599\||^1999\||^2298\||^2299\||^2403\|/' "#{working_path}" > "#{filtered_file_path}"
However, when I attempt to use it in Ruby on Rails using backticks, the resulting file is empty:
`awk '!/^1499\||^1598\||^1599\||^1999\||^2298\||^2299\||^2403\|/' "#{working_path}" > "#{filtered_file_path}"`
An awk with a simple regex works. For example:
`awk '!/SMITH/' "#{working_path}" > "#{filtered_file_path}"`
So, the issue appears to be with the escaped pipe characters.
Ideas?
Some background I should have provided:
The file I am processing is pipe-delimited. I am filtering out lines with certain codes that are in the first value on the line. So, the regex I am using is something like ^2298\|.
The other pipes in the expression in single quotes are regex OR operators.
"working_path" and "filtered_file_path" are Ruby variables.
I just figured it out. The backslash that is escaping the pipe characters also needs to be escaped. Not sure why there is a difference between the regular Terminal and Ruby, but there it is. The working version:
`awk '!/^1499\\||^1598\\||^1599\\||^1999\\||^2298\\||^2299\\||^2403\\|/' "#{working_path}" > "#{filtered_file_path}"`
After challenging my assumption that the problem was Ruby on Rails, the accepted answer here is what explained it:
Pipe symbol | in AWK field delimiter

How to define a ruby array that contains a backslash("\") character?

I want to define an array in ruby in following manner
A = ["\"]
I am stuck here for hours now. Tried several possible combinations of single and double quotes, forward and backward slashes. Alas !!
I have seen this link as well : here
But couldn't understand how to resolve my problem.
Apart from this what I need to do is -
1. Read a file character by character (which I managed to do !)
2. This file contains a "\" character
3. I want to do something if my array A includes this backslash
A.includes?("\")
Any help appreciated !
There are some characters which are special and need to be escaped.
Like when you define a string
str = " this is test string \
and this contains multiline data \
do you understand the backslash meaning here \
it is being used to denote the continuation of line"
In a string defined in a double quotes "", if you need to have a double quote how would you doo that? "\"", this is why when you put a backslash in a string you are telling interpretor you are going to use some special characters and which are escaped by backslash. So when you read a "\" from a file it will be read as "\" this into a ruby string.
char = "\\"
char.length # => 1
I hope this helps ;)
Your issue is not with Array, your question really involves escape sequences for special characters in strings. As the \ character is special, you need to first prepend it (escape it) with a leading backslash, like so.
"\\"
You should also re-read your link and the section on escape sequences.
You can escape backslash with a backslash in double quotes like:
["\\"].include?("\\")

Non-regexp version of gsub in Ruby

I am looking for a version of gsub which doesn't try to interpret its input as regular expressions and uses normal C-like escaped strings.
Update
The question was initiated by a strange behavior:
text.gsub("pattern", "\\\\\\")
and
text.gsub("pattern", "\\\\\\\\")
are treated as the same, and
text.gsub("pattern", "\\\\")
is treated as single backslash.
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("\\") {"\\\\"}
gsub accepts strings as first parameter:
the pattern is typically a Regexp; if given as
a String, any regular expression metacharacters
it contains will be interpreted literally
Example:
"hello world, i am thy code".gsub("o", "-foo-")
=> "hell-foo- w-foo-rld, i am thy c-foo-de"

How do I remove this backslash in Ruby

How do I remove this backslash?
s = "\""
I have tried s.gsub("\\", "") and that doesn't remove it, it returns the same string.
there's actually no backslash character in your String. The Backslash in your example simply escapes the following double quote and prevent's that it would terminate the string and thereby resulting in a syntax error (unterminated double quote ).
So what you see when you print that string in IRB is actually not the backslash as is, but the backslash in combination with the following dobule quote as an indication that the double quote is escaped. Kind of hard to grasp when you encounter it the first time. Have a look at http://en.wikibooks.org/wiki/Ruby_Programming/Strings#Escape_sequences
long story short: there is no backslash in your string so you can't remove it :)
gsub takes a regular expression as the first parameter. I believe that if you pass it a string, it will first convert it into a regex. This means you need extra escaping:
s.gsub("\\\\", "")
If you use regex notation, you can stop it from doubling up:
s.gsub(/\\/, "")
This is because you don't have to escape twice: once because double-quoted strings need you to escape the \ character, and once because the regular expression requires you to as well.
that's actually an escape quote sign (do a print s to see it)
I'm not sure if this is a solution to YOUR problem, but seeing that this is one of the first SO questions I looked at when trying to solve my problem and have in fact, solved it, here is what I did to fix my problem.
So I had some CSV.read output with a load of \ (backslashes) and unwanted quotation marks.
arr_of_arrays = CSV.read("path/to/file.csv")
processed_csv = arr_of_arrs.map {|t| eval(t)}
the key here is the eval() method.

Regular expression in Ruby

Could anybody help me make a proper regular expression from a bunch of text in Ruby. I tried a lot but I don't know how to handle variable length titles.
The string will be of format <sometext>title:"<actual_title>"<sometext>. I want to extract actual_title from this string.
I tried /title:"."/ but it doesnt find any matches as it expects a closing quotation after one variable from opening quotation. I couldn't figure how to make it check for variable length of string. Any help is appreciated. Thanks.
. matches any single character. Putting + after a character will match one or more of those characters. So .+ will match one or more characters of any sort. Also, you should put a question mark after it so that it matches the first closing-quotation mark it comes across. So:
/title:"(.+?)"/
The parentheses are necessary if you want to extract the title text that it matched out of there.
/title:"([^"]*)"/
The parentheses create a capturing group. Inside is first a character class. The ^ means it's negated, so it matches any character that's not a ". The * means 0 or more. You can change it to one or more by using + instead of *.
I like /title:"(.+?)"/ because of it's use of lazy matching to stop the .+ consuming all text until the last " on the line is found.
It won't work if the string wraps lines or includes escaped quotes.
In programming languages where you want to be able to include the string deliminator inside a string you usually provide an 'escape' character or sequence.
If your escape character was \ then you could write something like this...
/title:"((?:\\"|[^"])+)"/
This is a railroad diagram. Railroad diagrams show you what order things are parsed... imagine you are a train starting at the left. You consume title:" then \" if you can.. if you can't then you consume not a ". The > means this path is preferred... so you try to loop... if you can't you have to consume a '"' to finish.
I made this with https://regexper.com/#%2Ftitle%3A%22((%3F%3A%5C%5C%22%7C%5B%5E%22%5D)%2B)%22%2F
but there is now a plugin for Atom text editor too that does this.

Resources