GSUB and Forward Slash usage in Ruby - ruby

I often see the gsub function being called with the pattern parameter enclosed in forward slashes. For example:
>> phrase = "*** and *** ran to the ###."
>> phrase.gsub(/\*\*\*/, "WOOF")
=> "WOOF and WOOF ran to the ###."
I thought maybe it had something to do with escaping asterisks, but using single quotes and double quotes works just as well:
>> phrase = "*** and *** ran to the ###."
>> phrase.gsub('***', "WOOF")
=> "WOOF and WOOF ran to the ###."
>> phrase.gsub("***", "WOOF")
=> "WOOF and WOOF ran to the ###."
Is it just convention to use forward slash? What am I missing?

Use forward slashes if you need to use regular expressions.
If you use a string argument with gsub, it will just do a plain character match.
In your example, you need backslashes to escape the asterisks when using a regular expression, because asterisks have a special meaning in regex (optionally match something any number of times). They are not necessary when using a string, because they are just matched exactly.
In your example, you probably don't need to use a regular expression, since it is a simple pattern. However, if you wanted to match *** only when it was at the beginning of a string (e.g. the first bunch in your example), then you would want to use a regex, for example:
phrase.gsub(/^\*{3}/, "WOOF")
For more information on regular expressions, see: http://www.regular-expressions.info/.
For more information on using regular expressions in Ruby, see: http://ruby-doc.org/core-2.2.0/Regexp.html.
To play with regular expressions as they work in Ruby, try: http://rubular.com/.

You are missing reading the documentation:
The pattern is typically a Regexp; if given as a String, any regular expression metacharacters it contains will be interpreted literally, e.g. '\d' will match a backlash followed by ā€˜dā€™, instead of a digit.
http://ruby-doc.org/core-2.1.4/String.html#method-i-gsub
In other words, you can give a string or a regular expression. Regular expressions can be delimited several ways:
Regexps are created using the /.../ and %r{...} literals, and by the Regexp::new constructor.
http://ruby-doc.org/core-2.2.2/Regexp.html
The benefit of %r and of the alternate %r delimiters is you can usually find a delimiter that doesn't collide with characters in the pattern, which would force escaping them, as in your example.
* has to be escaped because it has special meaning in a regex, but in a string it does not.

Related

How to get three consecutive backslashes in Regexp

I want to create a regular expression such as:
/\\\s*\\\s*$/
I am trying it in this way:
Regexp.new('\\\s*\\\s*$') # => /\\s*\\s*$/
What am I doing wrong?
Well (\\) matches a single backslash. Backslash serves as an escape character for Regexp.
rgx = Regexp.new('\\\\\\s*\\\\\\s*$')
A more verbose way of doing this would be the following as #Cary Swoveland stated.
rgx = Regexp.new('\\{3}s*\\{3}s*$')
Using literal notation avoids some confusion. This compiles to what you said you want:
/\\\s*\\\s*$/
Though, to be clear, this still matches a single backslash, optional whitespace a single backslash and more optional whitespace. Backslashes are escaped when you inspect a regexp.

How come you can't gsub this string in Ruby?

These \\n are showing up in my strings even though it should only be \n.
But if I do this :
"\n".gsub('\\n','\b')
It returns :
"\n"
Ideally, I'm trying to find a regex that could rewrite this string :
"R3pQvDqmz/EQ7zho2mhIeE6UB4dLa6GUH7173VEMdGCcdsRm5pernkqCgbnj\\nZjTX\\n"
To not display two backslashes, but just one like this :
"R3pQvDqmz/EQ7zho2mhIeE6UB4dLa6GUH7173VEMdGCcdsRm5pernkqCgbnj\nZjTX\n"
But any of the regex I do will not work. I can gsub out the \n and put something like X there, but if I put a \ in it, then Ruby escapes it with an additional \ which consequentially destroys my encryption module as it needs to be specific.
Any ideas?
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")

ruby .split('\n') not splitting on new line

Why does this string not split on each "\n"? (RUBY)
"ADVERTISING [7310]\n\t\tIRS NUMBER:\t\t\t\t061340408\n\t\tSTATE OF INCORPORATION:\t\t\tDE\n\t\tFISCAL YEAR END:\t\t\t0331\n\n\tFILING VALUES:\n\t\tFORM TYPE:\t\t10-Q\n\t\tSEC ACT:\t\t1934 Act\n\t".split('\n')
>> ["ADVERTISING [7310]\n\t\tIRS NUMBER:\t\t\t\t061340408\n\t\tSTATE OF INCORPORATION:\t\t\tDE\n\t\tFISCAL YEAR END:\t\t\t0331\n\n\tFILING VALUES:\n\t\tFORM TYPE:\t\t10-Q\n\t\tSEC ACT:\t\t1934 Act\n\t"]
You need .split("\n"). String interpolation is needed to properly interpret the new line, and double quotes are one way to do that.
In Ruby single quotes around a string means that escape characters are not interpreted. Unlike in C, where single quotes denote a single character. In this case '\n' is actually equivalent to "\\n".
So if you want to split on \n you need to change your code to use double quotes.
.split("\n")
Ruby has the methods String#each_line and String#lines
returns an enum:
http://www.ruby-doc.org/core-1.9.3/String.html#method-i-each_line
returns an array:
http://www.ruby-doc.org/core-2.1.2/String.html#method-i-lines
I didn't test it against your scenario but I bet it will work better than manually choosing the newline chars.
Or a regular expression
.split(/\n/)
You can't use single quotes for this:
"ADVERTISING [7310]\n\t\tIRS NUMBER:\t\t\t\t061340408\n\t\tSTATE OF INCORPORATION:\t\t\tDE\n\t\tFISCAL YEAR END:\t\t\t0331\n\n\tFILING VALUES:\n\t\tFORM TYPE:\t\t10-Q\n\t\tSEC ACT:\t\t1934 Act\n\t".split("\n")

How to make Ruby ignore backslash in strings?

Is there some way in Ruby that I can avoid having to put double-backslash in Ruby strings (like what can be done in C#):
For example, in C# was can prefix a string with # and then the backslash in the string does not need to be escaped:
#"C:\Windows, C:\ABC"
Without # we would need to escape the backslash:
"C:\\Windows, C:\\ABC"
Is there something similar in Ruby?
Use single quotes
my_string = 'C:\Windows'
See more in the Strings section here
You can also use %q and backslashes will be automatically escaped for you:
%q{C:\Windows} => "C:\\Windows"

Ruby RegEx problem text.gsub[^\W-], '') fails

I'm trying to learn RegEx in Ruby, based on what I'm reading in "The Rails Way". But, even this simple example has me stumped. I can't tell if it is a typo or not:
text.gsub(/\s/, "-").gsub([^\W-], '').downcase
It seems to me that this would replace all spaces with -, then anywhere a string starts with a non letter or number followed by a dash, replace that with ''. But, using irb, it fails first on ^:
syntax error, unexpected '^', expecting ']'
If I take out the ^, it fails again on the W.
>> text = "I love spaces"
=> "I love spaces"
>> text.gsub(/\s/, "-").gsub(/[^\W-]/, '').downcase
=> "--"
Missing //
Although this makes a little more sense :-)
>> text.gsub(/\s/, "-").gsub(/([^\W-])/, '\1').downcase
=> "i-love-spaces"
And this is probably what is meant
>> text.gsub(/\s/, "-").gsub(/[^\w-]/, '').downcase
=> "i-love-spaces"
\W means "not a word"
\w means "a word"
The // generate a regexp object
/[^\W-]/.class
=> Regexp
Step 1: Add this to your bookmarks. Whenever I need to look up regexes, it's my first stop
Step 2: Let's walk through your code
text.gsub(/\s/, "-")
You're calling the gsub function, and giving it 2 parameters.
The first parameter is /\s/, which is ruby for "create a new regexp containing \s (the // are like special "" for regexes).
The second parameter is the string "-".
This will therefore replace all whitespace characters with hyphens. So far, so good.
.gsub([^\W-], '').downcase
Next you call gsub again, passing it 2 parameters.
The first parameter is [^\W-]. Because we didn't quote it in forward-slashes, ruby will literally try run that code. [] creates an array, then it tries to put ^\W- into the array, which is not valid code, so it breaks.
Changing it to /[^\W-]/ gives us a valid regex.
Looking at the regex, the [] says 'match any character in this group. The group contains \W (which means non-word character) and -, so the regex should match any non-word character, or any hyphen.
As the second thing you pass to gsub is an empty string, it should end up replacing all the non-word characters and hyphens with empty string (thereby stripping them out )
.downcase
Which just converts the string to lower case.
Hope this helps :-)
You forgot the slashes. It should be /[^\W-]/
Well, .gsub(/[^\W-]/,'') says replace anything that's a not word nor a - for nothing.
You probably want
>> text.gsub(/\s/, "-").gsub(/[^\w-]/, '').downcase
=> "i-love-spaces"
Lower case \w (\W is just the opposite)
The slashes are to say that the thing between them is a regular expression, much like quotes say the thing between them is a string.

Resources