urls from gsub not correct - ruby-on-rails

I have some problems when I try to check urls after I get them using the gsub method.
From the console it works fine:
('http://ale.it' =~ URI::regexp).nil?.to_s
=> "false"
but if i launch this it doesn't work:
"http://ale.it".gsub(/http[s]?:\/\/[^\s]+/, ('\0' =~ URI::regexp).nil?.to_s)
=> "true"
How can I get correct urls?

This is an explanation of what your 2 examples do. Whilst it isn't really an answer it's a bit long to fit in a comment.
=~ returns the position where a match occurs or nil if no match is found.
In your first example 'http://ale.it' matches URI::regexp starting at position 0 so you get 0.nil? which is false, converted to a string "false"
gsub in your second example takes 2 parameters, a pattern and a replacement string and replaces all matches of the pattern with the replacement.
'\0' doesn't match URI::regexp so ('\0' =~ URI::regexp).nil? is true and with to_s applied is the string "true".
"http://ale.it" matches /http[s]?:\/\/[^\s]+/ so gets replaced with "true".
You will have to expand your question to explain what you're trying to achieve.

i solved with:
"http://ale.it".gsub(/http[s]?:\/\/[^\s]+/) do |m|
(m =~ URI::regexp).nil?.to_s)
end

Related

How to use gsub twice?

I need to perform to search and replace activity
"{{content}}" => replace. (this to keep same type) regex gsub(/"{{(.*?)}}"/)
"hello {{content}}" => repalce (this to replace from string) regex gsub(/{{(.*?)}}/)
Method that i build is
def fill_in(template)
template.gsub(/\"\{\{(.*?)\}\}\"/) do
"test"
end
end
Tried template.gsub(/\"\{\{(.*?)\}\}\"/).gsub(/\{\{(.*?)\}\}/) do but this is giving
me error
undefined method `gsub' for #<Enumerator:
"{{user_name}}":gsub(/"{{(.*?)}}"/)>
first gsub is priority if it matches that pattern replace based on then if not check for second gsub
template.gsub(/\"\{\{(.*?)\}\}\"/) do
# content will be replaced from the data object
end.gsub(/\"\{\{(.*?)\}\}\"/) do
# content will be replaced from the data object
end
do body for both gsub is same, how to stop this repetition
The gsub with just a regex as a single argument to return an Enumerator, so you won't be able to chain the gsub in this way.
You can combine the two patterns into one:
/(")?\{\{(.*?)\}\}(?(1)"|)/
See the regex demo. Details:
(")? - Capturing group 1 (optional):
\{\{ - a {{ text
(.*?) - Capturing group 2: any zero or more chars other than line break chars, as few as possible (if you need to match line breaks, too, use ((?s:.*?)) instead, or simply add /m flag)
\}\} - a }} string
(?(1)"|) - a conditional construct: if Group 1 matched, match ", else, match an empty string.
In the code, you will need to check if Group 1 matched, and if so, implement one replacement logic, else, use another replacement logic. See the Ruby demo:
def fill_in(template)
template.gsub(/(")?\{\{(.*?)\}\}(?(1)"|)/) {
$~[1] ? "Replacement 1" : "Replacement 2"
}
end
p fill_in('"{{hello}}" and {{hello}}')
# => "Replacement 1 and Replacement 2"

Ruby on Rails: Checking for valid regex does not work properly, high false rate

In my application I've got a procedure which should check if an input is valid or not. You can set up a regex for this input.
But in my case it returns false instead of true. And I can't find the problem.
My code looks like this:
gaps.each_index do | i |
if gaps[i].first.starts_with? "~"
# regular expression
begin
regex = gaps[i].first[1..-1]
# a pipe is used to seperate the regex from the solution-string
if regex.include? "|"
puts "REGEX FOUND ------------------------------------------"
regex = regex.split("|")[0..-2].join("|")
end
reg = Regexp.new(regex, true)
unless reg.match(data[i])
puts "REGEX WRONGGGG -------------------"
#wrong_indexes << i
end
rescue
end
else
# normal string
if data[i].nil? || data[i].strip != gaps[i].first.strip
#wrong_indexes << i
end
end
An example would be:
[[~berlin|berlin]]
The left one before the pipe is the regex and the right one next to the pipe is the correct solution.
This easy input should return true, but it doesn't.
Does anyone see the problem?
Thank you all
EDIT
Somewhere in this lines must be the problem:
if regex.include? "|"
puts "REGEX FOUND ------------------------------------------"
regex = regex.split("|")[0..-2].join("|")
end
reg = Regexp.new(regex, true)
unless reg.match(data[i])
Update: Result without ~
The whole point is that you are initializing regex using the Regexp constructor
Constructs a new regular expression from pattern, which can be either a String or a Regexp (in which case that regexp’s options are propagated, and new options may not be specified (a change as of Ruby 1.8).
However, when you pass the regex (obtained with regex.split("|")[0..-2].join("|")) to the constructor, it is a string, and reg = Regexp.new(regex, true) is getting ~berlin (or /berlin/i) as a literal string pattern. Thus, it actually is searching for something you do not expect.
See, regex= "[[/berlin/i|berlin]]" only finds a *literal /berlin/i text (see demo).
Also, you need to get the pattern from the [[...]], so strip these brackets with regex = regex.gsub(/\A\[+|\]+\z/, '').split("|")[0..-2].join("|").
Note you do not need to specify the case insensitive options, since you already pass true as the second parameter to Regexp.new, it is already case-insensitive.
If you are performing whole word lookup, add word boundaries: regex= "[[\\bberlin\\b|berlin]]" (see demo).

string regex on ruby on rails

how to make sure my string format must be like this :
locker_number=3,email=ucup#gmail.com,mobile_phone=091332771331,firstname=ucup
i want my string format `"key=value,"
how to make regex for check my string on ruby?
This regex will find what you're after.
\w+=.*?(,|$)
If you want to capture each pairing use
(\w+)=(.*?)(?:,|$)
http://rubular.com/r/A2ernIzQkq
The \w+ is one or more occurrences of a character a-z, 1-9, or an underscore. The .*? is everything until the first , or the end of the string ($). The pipe is or and the ?: tells the regex no to capture that part of the expression.
Per your comment it would be used in Ruby as such,
(/\w+=.*?(,|$)/ =~ my_string) == 0
You can use a regex like this:
\w+=.*?(,|$)
Working demo
You can use this code:
"<your string>" =~ /\w+=.*?(,|$)/
What about something like this? It's picky about the last element not ending with ,. But it doesn't enforce the need for no commas in the key or no equals in the value.
'locker_number=3,email=ucup#gmail.com,mobile_phone=091332771331,firstname=ucup' =~ /^([^=]+=[^,]+,)*([^=]+=[^,]+)$/

string format check

Suppose I have string variables like following:
s1="10$"
s2="10$ I am a student"
s3="10$Good"
s4="10$ Nice weekend!"
As you see above, s2 and s4 have white space(s) after 10$ .
Generally, I would like to have a way to check if a string start with 10$ and have white-space(s) after 10$ . For example, The rule should find s2 and s4 in my above case. how to define such rule to check if a string start with '10$' and have white space(s) after?
What I mean is something like s2.RULE? should return true or false to tell if it is the matched string.
---------- update -------------------
please also tell the solution if 10# is used instead of 10$
You can do this using Regular Expressions (Ruby has Perl-style regular expressions, to be exact).
# For ease of demonstration, I've moved your strings into an array
strings = [
"10$",
"10$ I am a student",
"10$Good",
"10$ Nice weekend!"
]
p strings.find_all { |s| s =~ /\A10\$[ \t]+/ }
The regular expression breaks down like this:
The / at the beginning and the end tell Ruby that everything in between is part of the regular expression
\A matches the beginning of a string
The 10 is matched verbatim
\$ means to match a $ verbatim. We need to escape it since $ has a special meaning in regular expressions.
[ \t]+ means "match at least one blank and/or tab"
So this regular expressions says "Match every string that starts with 10$ followed by at least one blank or tab character". Using the =~ you can test strings in Ruby against this expression. =~ will return a non-nil value, which evaluates to true if used in a conditional like if.
Edit: Updated white space matching as per Asmageddon's suggestion.
this works:
"10$ " =~ /^10\$ +/
and returns either nil when false or 0 when true. Thanks to Ruby's rule, you can use it directly.
Use a regular expression like this one:
/10\$\s+/
EDIT
If you use =~ for matching, note that
The =~ operator returns the character position in the string of the
start of the match
So it might return 0 to denote a match. Only a return of nil means no match.
See for example http://www.regular-expressions.info/ruby.html on a regular expression tutorial for ruby.
If you want to proceed to cases with $ and # then try this regular expression:
/^10[\$#] +/

Regex problem with match method

I want validate many mails ( one or more) with regex expression but this attribute don´t belongs to any model. So I wrote a method:
def emails_are_valid?(emails)
#regex with validation
regex = Regexp.new("^(\s*[a-zA-Z0-9\._%-]+#[a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4}\s*([,]{1}[\s]*[a-zA-Z0-9\._%-]+#[a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4}\s*)*)$")
#if the quantity of emails is zero o its validations is bad return false.
if emails.blank? || emails.match(regex).nil?
return false
else
return true
end
end
I evaluate this string mm#somedomain.com aa, mma#somedomain.com when
I tested this regex in http://www.rubular.com/ is bad (no matches).
So According to this page my regex is ok.
But when I evaluate emails.match(regex).nil? that returns me false (So the string is valid, but this string is bad)
Please I need help. my regex is bad or my emails_are_valid? method is bad or match method is bad.
Thanks in advance.
You should have used single quotes instead of double quotes when declaring your regex, otherwise \s gets parsed as an escape sequence.
Change that line to
regex = Regexp.new('^(\s*[a-zA-Z0-9\._%-]+#[a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4}\s*([,]{1}[\s]*[a-zA-Z0-9\._%-]+#[a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4}\s*)*)$')
and the method will work.
On a side note, this would be a more concise way of doing the same thing - http://codepad.org/YbsqIkcP

Resources