regex replace [ with \[ - ruby

I want to write a regex in Ruby that will add a backslash prior to any open square brackets.
str = "my.name[0].hello.line[2]"
out = str.gsub(/\[/,"\\[")
# desired out = "my.name\[0].hello.line\[2]"
I've tried multiple combinations of backslashes in the substitution string and can't get it to leave a single backslash.

You don't need a regular expression here.
str = "my.name[0].hello.line[2]"
puts str.gsub('[', '\[')
# my.name\[0].hello.line\[2]

I tried your code and it worked correct:
str = "my.name[0].hello.line[2]"
out = str.gsub(/\[/,"\\[")
puts out #my.name\[0].hello.line\[2]
If you replace putswith p you get the inspect-version of the string:
p out #"my.name\\[0].hello.line\\[2]"
Please see the " and the masked \. Maybe you saw this result.
As Daniel already answered: You can also define the string with ' and don't need to mask the values.

Related

best way to find substring in ruby using regular expression

I have a string https://stackverflow.com. I want a new string that contains the domain from the given string using regular expressions.
Example:
x = "https://stackverflow.com"
newstring = "stackoverflow.com"
Example 2:
x = "https://www.stackverflow.com"
newstring = "www.stackoverflow.com"
"https://stackverflow.com"[/(?<=:\/\/).*/]
#⇒ "stackverflow.com"
(?<=..) is a positive lookbehind.
If string = "http://stackoverflow.com",
a really easy way is string.split("http://")[1]. But this isn't regex.
A regex solution would be as follows:
string.scan(/^http:\/\/(.+)$/).flatten.first
To explain:
String#scan returns the first match of the regex.
The regex:
^ matches beginning of line
http: matches those characters
\/\/ matches //
(.+) sets a "match group" containing any number of any characters. This is the value returned by the scan.
$ matches end of line
.flatten.first extracts the results from String#scan, which in this case returns a nested array.
You might want to try this:
#!/usr/bin/env ruby
str = "https://stackoverflow.com"
if mtch = str.match(/(?::\/\/)(/S)/)
f1 = mtch.captures
end
There are two capturing groups in the match method: the first one is a non-capturing group referring to your search pattern and the second one referring to everything else afterwards. After that, the captures method will assign the desired result to f1.
I hope this solves your problem.

Get a string using regular expressin in ruby

I have some strings like this
../..//somestring
../somestring
../..somestring
./somestring
How to write a regular expression in ruby to extract "somestring" from above strings. Before some strings it can be any combination of . and /
Thanks for you help
Do this:
string.sub(/\A[.\/]+/, "")
"../../test/file/cases".sub(/\A[.\/]+/, "")
# => "test/file/cases"
Just match letters:
str = "../..//somestring" # or "../somestring", "../..somestring", "./somestring"
str[/[a-z]+/] # somestring
RE: your comment
If you just want to remove leading dots and slashes, use
str.gsub(/[.\/]/, '')
It looks like you're dealing with file paths. If so, there are more appropriate tools than regexps
File.basename('../..//somestring')
# "somestring"
regexp = /^[.\/]+(.*?)$/i
result = subject.scan(regexp)
http://rubular.com/r/tMYKPe78uc

Reformatting dates

I'm trying to reformat German dates (e.g. 13.03.2011 to 2011-03-13).
This is my code:
str = "13.03.2011\n14:30\n\nHannover Scorpions\n\nDEG Metro Stars\n60\n2 - 3\n\n\n\n13.03.2011\n14:30\n\nThomas Sabo Ice Tigers\n\nKrefeld Pinguine\n60\n2 - 3\n\n\n\n"
str = str.gsub("/(\d{2}).(\d{2}).(\d{4})/", "/$3-$2-$1/")
I get the same output like input. I also tried my code with and without leading and ending slashes, but I don't see a difference. Any hints?
I tried to store my regex'es in variables like find = /(\d{2}).(\d{2}).(\d{4})/ and replace = /$3-$2-$1/, so my code looked like this:
str = "13.03.2011\n14:30\n\nHannover Scorpions\n\nDEG Metro Stars\n60\n2 - 3\n\n\n\n13.03.2011\n14:30\n\nThomas Sabo Ice Tigers\n\nKrefeld Pinguine\n60\n2 - 3\n\n\n\n"
find = /(\d{2}).(\d{2}).(\d{4})/
replace = /$3-$2-$1/
str = str.gsub(find, replace)
TypeError: no implicit conversion of Regexp into String
from (irb):4:in `gsub'
Any suggestions for this problem?
First mistake is the regex delimiter. You do not need place the regex as string. Just place it inside a delimiter like //
Second mistake, you are using captured groups as $1. Replace those as \\1
str = str.gsub(/(\d{2})\.(\d{2})\.(\d{4})/, "\\3-\\2-\\1")
Also, notice I have escaped the . character with \., because in regex . means any character except \n

Escaping single and double quotes in a string in ruby?

How can I escape single and double quotes in a string?
I want to escape single and double quotes together. I know how to pass them separately but don't know how to pass both of them.
e.g: str = "ruby 'on rails" " = ruby 'on rails"
My preferred way is to not worry about escaping and instead use %q, which behaves like a single-quote string (no interpolation or character escaping), or %Q for double quoted string behavior:
str = %q[ruby 'on rails" ] # like single-quoting
str2 = %Q[quoting with #{str}] # like double-quoting: will insert variable
See https://docs.ruby-lang.org/en/trunk/syntax/literals_rdoc.html#label-Strings and search for % strings.
Use backslash to escape characters
str = "ruby \'on rails\" "
Here is a complete list:
From http://learnrubythehardway.org/book/ex10.html
You can use Q strings which allow you to use any delimiter you like:
str = %Q|ruby 'on rails" " = ruby 'on rails|
>> str = "ruby 'on rails\" \" = ruby 'on rails"
=> "ruby 'on rails" " = ruby 'on rails"
I would go with a heredoc if I'm starting to have to worry about escaping. It will take care of it for you:
string = <<MARKER
I don't have to "worry" about escaping!!'"!!
MARKER
MARKER delineates the start/end of the string. start string on the next line after opening the heredoc, then end the string by using the delineator again on it's own line.
This does all the escaping needed and converts to a double quoted string:
string
=> "I don't have to \"worry\" about escaping!!'\"!!\n"
I would use just:
str = %(ruby 'on rails ")
Because just % stands for double quotes(or %Q) and allows interpolation of variables on the string.
Here is an example of how to use %Q[] in a more complex scenario:
%Q[
<meta property="og:title" content="#{#title}" />
<meta property="og:description" content="#{#fullname}'s profile. #{#fullname}'s location, ranking, outcomes, and more." />
].html_safe
One caveat:
Using %Q[] and %q[] for string comparisons is not intuitively safe.
For example, if you load something meant to signify something empty, like "" or '', you need to use the actual escape sequences. For example, let's say qvar equals "" instead of any empty string.
This will evaluate to false
if qvar == "%Q[]"
As will this,
if qvar == %Q[]
While this will evaluate to true
if qvar == "\"\""
I ran into this issue when sending command-line vars from a different stack to my ruby script. Only Gabriel Augusto's answer worked for me.

Issue dealing with white space with Ruby regular expressions

I'm trying to write a simple script expression that allows me to identify the java files in a directory that have a private constructor. I have had some luck but I want my script to acknowledge there is white space between the access modifier and the constructor name but not care if it is a space or n spaces or a tab or n tabs etc.
I am trying to use...
"private\s+"+object_name
but the + (1 or more) is not finding a constructor with 2 spaces between the modifier and the constructor name.
I know I am missing something. Any help would be greatly appreciated.
Thanks.
Here is the full code if it helps...
!#/usr/bin/ruby
path = ARGV[0]
if path.nil?
puts "missing path argument"
exit
end
entries = Dir.entries( path )
entries.each do |file_name|
file_name = file_name.rstrip
if ( file_name.end_with? "java" )
text = File.read( path+file_name )
object_name = file_name.chomp( ".java" )
search_str = "private\s+"+object_name
matches = text.match( Regexp.escape( search_str ) )
if ( !matches.nil? && matches.length > 0 )
puts matches
end
end
end
I think you want to escape the \ in your Ruby string and also Regexp.escape your object name and not the whole regex including the whitespace matcher, e.g.,
[...]
search_regex = Regexp.new("private\\s+" + Regexp.escape(object_name))
matches = text.match(search_regex)
As #LBg also points out, if you want to use + concatenation, better to use single quotes that won't require escaping the \. Or use doubles with substitution as in:
search_regex = Regexp.new("private\\s+#{Regexp.escape(object_name)}")
A double-quoted string reads "\s" as " ", no problems with that, but prefer use single-quoted in this case. Regexp.escape removes the funcionality of the regex's symbols of the string. private + ("\s" is " ") is converted to private\ \+ and, with match, will try to find the string private +object_name, what is not what you want. Remove the Regexp.escape and it should work well.

Resources