Ruby: .grep with regex - ruby

I'm using a regular expression to replace all '*' with '[A-Za-z0-9]*' except when the '*' is preceded by '\' like '\*'. How can I ignore the case '\*' ?
code:
puts Regexp.new(val.gsub(/^\*/,'[A-Za-z0-9]*')) =~ str ? 'true' : 'false'

You can use a Negative Lookbehind assertion here.
"foo\\* bar* baz* quz\\*".gsub(/(?<!\\)\*/, '[A-Za-z0-9]*')
# => 'foo\* bar[A-Za-z0-9]* baz[A-Za-z0-9]* quz\*'

You can do this by being more particular in your substitutions:
tests = [
"*.foo",
"\\*.foo"
]
tests.each do |test|
r = test.gsub(/(\\\*|\*)/) do |s|
case ($1)
when "\\*"
$1
else
"[A-Za-z0-9]*"
end
end
puts r
end
Results for me:
[A-Za-z0-9]*.foo
\*.foo
The first capture looks for \* specifically.

Related

Condense several conditional statement comparing the same value

I want to know if there is a way to condense this line of code:
elsif i == '+' || i == '-' || i == '/' || i == '*'
A case when control structure allows such a condensed line:
case i
when '+', '-', '/', '*' # <= condensed line of code
puts "operator!"
end
you could do
"+-/*".include?(i)
Similar to #Subash but you can also do this since:
#this returns the match string of i which is truthy or false if no match.
elsif "+-/*"[i]
if you want to return a boolean true or false you can also double bang
elsif !!"+-/*"[i] #true if matched, false if not
There are many variants of this in ruby, if you had a regex or some other type of string match you might also use
i = '/'
!!"+-/*".match(i) #true

Regular expression to match letter inside brackets

I need to write a regular expression that matches all strings containing one or more of the following substrings (including the curly brackets):
{NN}
{NNN}
{NNNN}
{NNNNN}
{NNNNNN}
I am completely new to regular expressions. Can anybody help?
r = /
\{ # match left brace
N{2,6} # match between 2 and 6 Ns
\} # match right brace
/x # free-spacing regex definition mode
arr = %w|{N} {NN} {NNN} {NNNN} {NNNNN} {NNNNNN} {NNNNNNN} {NNMN}|
#=> ["{N}", "{NN}", "{NNN}", "{NNNN}", "cat{NNNNN}dog", "{NNNNNN}",
# "{NNNNNNN}", "{NNMN}"]
arr.each { |s| puts "'#{s}'.match(r) = #{s.match?(r)}" }
'{N}'.match(r) = false
'{NN}'.match(r) = true
'{NNN}'.match(r) = true
'{NNNN}'.match(r) = true
'cat{NNNNN}dog'.match(r) = true
'{NNNNNN}'.match(r) = true
'{NNNNNNN}'.match(r) = false
'{NNMN}'.match(r) = false
You didn't specify language / interface you'd be using... In general: \{.*?\} . Replace .*? with N{2,6}? if you want to match only the string you presented.
Ruby example:
if ( content =~ /\{N{2,6}\}/ )
puts "Content match!"
end

Testing Regex in If, Else Statement

I think I'm close, but the regex isn't evaluating. Hoping someone may know why.
def new_title(title)
words = title.split(' ')
words = [words[0].capitalize] + words[1..-1].map do |w|
if w =~ /and|an|a|the|in|if|of/
w
else
w.capitalize
end
end
words.join(' ')
end
When I pass in lowercase titles, they get returned as lowercase.
You need to properly anchor your regular expression:
new_title("the last hope")
# => "The last Hope"
This is because /a/ matches a word with an a in it. /\Aa\Z/ matches a string that consists entirely of a, and /\A(a|of|...)\Z/ matches against a set of words.
In any case, what you might want is this:
case (w)
when 'and', 'an', 'a', 'the', 'in', 'if', 'of'
w
else
w.capitalize
end
Using a regular expression here is a bit heavy handed. What you want is an exclusion list.
This is called titleize, and is implemented like this:
def titleize(word)
humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
end
Se the doc.
If you want fancy titlezing, check out granth's titleize
Your regular expression should be checking the whole word (^word$). Anyway, isn't more simple to use Enumerable#include?:
def new_title(title)
words = title.split(' ')
rest_words = words.drop(1).map do |word|
%w(and an a the in if of).include?(word) ? word : word.capitalize
end
([words[0].capitalize] + rest_words).join(" ")
end

How to find string which is started with ".."?

I was trying to find strings out which is followed by only "..",but couldn't get that :
["..ab","...cc","..ps","....kkls"].each do |x|
puts x if /../.match(x)
end
..ab
...cc
..ps
....kkls
=> ["..ab", "...cc", "..ps", "....kkls"]
["..ab","...cc","..ps","....kkls"].each do |x|
puts x if /(.)(.)/.match(x)
end
..ab
...cc
..ps
....kkls
=> ["..ab", "...cc", "..ps", "....kkls"]
Expected output:
["..ab","..ps"]
What you want is
/^\.\.(?!\.)/
The caret ^ at the beginning means match the beginning of the string; periods must be escaped by a backslash as \. because in regular expressions a plain period . matches any character; the (?!\.) is a negative look-ahead meaning the next character is not a period. So the expression means, "at the beginning of the string, match two periods, which must be followed by a character which is not a period."
>> /^\.\.(?!\.)/.match "..ab"
=> #<MatchData "..">
>> /^\.\.(?!\.)/.match "...cc"
=> nil
Try selecting on /^\.\.[^\.]/ (starts with two dots and then not a dot).
ss = ["..ab","...cc","..ps","....kkls"]
ss.select { |x| x =~ /^\.\.[^\.]/ } # => ["..ab", "..ps"]
Try using /^\.{2}\w/ as the regular expression.
A quick explanation:
^ means the start of the string. Without this, it can match dots that are found in the middle of the string.
\. translates to . -- if you use the dot on its own, it will match any non-newline character
{2} means that you're looking for two of the dots. (you could rewrite /\.{2}/ as /\.\./)
Finally, the \w matches any word character (letter, number, underscore).
A really good place to test Ruby regular expressions is http://rubular.com/ -- it lets you play with the regex and test it right in your browser.
You don't need regex for this at all, you can just extract the appropriate leading chunks using String#[] or String#slice and do simple string comparisons:
>> a = ["..ab", "...cc", "..ps", "....kkls", ".", "..", "..."]
>> a.select { |s| s[0, 2] == '..' && s[0, 3] != '...' }
=> ["..ab", "..ps", ".."]
Maybe this:
["..ab","...cc","..ps","....kkls"].each {|x| puts x if /^\.{2}\w/.match(x) }
Or if you want to make sure the . doesn't match:
["..ab","...cc","..ps","....kkls"].each {|x| puts x if /^\.{2}[^\.]/.match(x) }

Refactoring a regular expression check in ruby

I'm thinking there has got to be a cleaner way to check if a regular expression is not nil / is true. This is what I have been using:
hold = (h4.text =~ /Blah/)
if !hold.nil?
...
end
I tried: !(h4.text =~ /Blah/).nil? but it did not seem to work.
You can use unless here:
unless h4.text =~ /Blah/
#...
end
if h4.text !~ /Blah/
# ...
end
#!/usr/bin/ruby1.8
text = 'Blah blah blah'
puts "blah" if text =~ /Blah/ # => blah
text = 'Foo bar baz'
puts "blah" if text =~ /Blah/ # (nothing printed)
In a Ruby conditional statement,
anything that is neither nil nor
false is considered to be true.
=~ returns nil for no match, or an integer character position if there
is a match.
nil is as good a false; an integer is
as good as true.
Therefore, you can use the result of =~ directly in an if, while, etc.
Neither of the above seemed to work, this is what I ended up with:
unless (h4.text =~ /Blah/) == nil
...
end

Resources