When i try to use:
Regexp.new("/regexp/i")
=> /\/regexp\/i/
But it's not what i want - i need:
/regexp/i
How i can convert this proper way?
···
--
Posted via http://www.ruby-forum.com/\.
When i try to use:
Regexp.new("/regexp/i")
=> /\/regexp\/i/
But it's not what i want - i need:
/regexp/i
How i can convert this proper way?
--
Posted via http://www.ruby-forum.com/\.
When i try to use:
Regexp.new("/regexp/i")
=> /\/regexp\/i/
But it's not what i want - i need:
/regexp/i
How i can convert this proper way?
Try without the quotes
Regexp.new(/regexp/i)
=> /regexp/i
Cheers,
2009/8/21 Joao Silva <rubyforum@thisisnotmyrealemail.com>:
--
JJ Fleck
PCSI1 Lycée Kleber
Joao Silva wrote:
When i try to use:
Regexp.new("/regexp/i")
=> /\/regexp\/i/
But it's not what i want - i need:
/regexp/i
How i can convert this proper way?
If that is exactly the kind of string you are expecting, I think you are stuck with having to use eval.
irb(main):001:0> r = eval("/regexp/i")
=> /regexp/i
irb(main):002:0> r.match("REGEXP")
=> #<MatchData "REGEXP">
If you do not need the options, you could just grab the inner part and make a regexp out of that:
irb(main):001:0> re = "/som.r.g.x\d+/i"
=> "/som.r.g.xd+/i"
irb(main):002:0> re = "/som.r.g.x\\d+/i".match(/\/(.*)\/[^\/]/)[1]
=> "som.r.g.x\\d+"
irb(main):003:0> /#{re}/.match("someregex1123")
=> #<MatchData "someregex1123">
Not really a great solution, though, as you lose information.
-Justin
Regexp.new(/regexp/i)
Joao Silva wrote:
When i try to use:
Regexp.new("/regexp/i")
=> /\/regexp\/i/
But it's not what i want - i need:
/regexp/i
How i can convert this proper way?
Joao Silva wrote:
When i try to use:
Regexp.new("/regexp/i")
=> /\/regexp\/i/
But it's not what i want - i need:
/regexp/i
How i can convert this proper way?
str = "/regexp/i"
pieces = str.split("/")
pattern = pieces[1]
my_regex = Regexp.new(pattern, true)
md = my_regex.match("hello ReGexP")
puts md[0]
--output:--
ReGexP
Or, more generally:
str = "/reg.*?exp/im"
pieces = str.split("/")
pattern = pieces[1]
flags = pieces[2]
arg_two = 0
flags.length.times do |i|
case flags[i, 1]
when "i"
arg_two |= Regexp::IGNORECASE
when "m"
arg_two |= Regexp::MULTILINE
when "x"
arg_two |= Regexp::EXTENDED
end
end
regex = Regexp.new(pattern, arg_two)
test_str =<<ENDOFSTRING
hello rEG
world exP
ENDOFSTRING
md = regex.match(test_str)
if md
puts md[0]
end
--output:--
rEG
world exP
--
Posted via http://www.ruby-forum.com/\.
class String
def to_r
Regexp.new(*strip.match(/\/(.*)\/(.*)/)[1,2])
end
end
"/regexp/i".to_r # => /regexp/i
On Fri, Aug 21, 2009 at 4:18 AM, Joao Silva < rubyforum@thisisnotmyrealemail.com> wrote:
When i try to use:
>> Regexp.new("/regexp/i")
=> /\/regexp\/i/But it's not what i want - i need:
/regexp/i
How i can convert this proper way?
--
Posted via http://www.ruby-forum.com/\.
In the spirit of http://xkcd.com/979/ here's a better answer:
http://rubygems.org/gems/to_regexp
This gem solves the problem. Source:
http://stackoverflow.com/questions/6669425/convert-a-regular-expression-in-a-string-to-a-regexp-object-in-ruby/6669653#6669653
Once this gem is installed, you can call String#to_regexp and all is
well.
--
Posted via http://www.ruby-forum.com/.
Something like:
key = "ixm"
x = str.reverse_index('/')
v = str[x+1..-1]
o = v.characters.inject(0){ |s,c| b = key.index(c); b ? 2**b : 0 }
Regexp.new(str[1...x], o)
Or
eval "%r#{str}"
If safety is a concern you can get Pretty Good(tm) safety by wrapping it in
a threaded $SAFE=4. Too bad Ruby doesn't support %R, then it would
perfectly safe.
Fleck Jean-Julien wrote:
2009/8/21 Joao Silva <rubyforum@thisisnotmyrealemail.com>:
How i can convert this proper way?
Try without the quotes
Regexp.new(/regexp/i)
=> /regexp/i
Cheers,
I cannot do this without quotes - i need get it from string. Only thing
i have is "/regexp/i" string.
Thanks!
--
Posted via http://www.ruby-forum.com/\.
Justin Collins wrote:
Joao Silva wrote:
When i try to use:
Regexp.new("/regexp/i")
=> /\/regexp\/i/
But it's not what i want - i need:
/regexp/i
How i can convert this proper way?
If that is exactly the kind of string you are expecting, I think you are stuck with having to use eval.irb(main):001:0> r = eval("/regexp/i")
=> /regexp/i
irb(main):002:0> r.match("REGEXP")
=> #<MatchData "REGEXP">If you do not need the options, you could just grab the inner part and make a regexp out of that:
irb(main):001:0> re = "/som.r.g.x\d+/i"
=> "/som.r.g.xd+/i"
irb(main):002:0> re = "/som.r.g.x\\d+/i".match(/\/(.*)\/[^\/]/)[1]
=> "som.r.g.x\\d+"
irb(main):003:0> /#{re}/.match("someregex1123")
=> #<MatchData "someregex1123">Not really a great solution, though, as you lose information.
-Justin
I should add, for the second approach you could also parse the options and then manually build up the regexp with the corresponding options. That is the "non-lazy" way, though
-Justin
Michal Zacik wrote:
Regexp.new(/regexp/i)
? Without ""?
--
Posted via http://www.ruby-forum.com/\.
Josh Cheek wrote:
class String
def to_r
Regexp.new(*strip.match(/\/(.*)\/(.*)/)[1,2])
end
end"/regexp/i".to_r # => /regexp/i
Doesn't work in this case:
str = "/reg.*?exp/m"
test_str =<<ENDOFSTRING
hello rEG
world exP
ENDOFSTRING
...nor when there is more than one flag.
--
Posted via http://www.ruby-forum.com/\.
Joao Silva <rubyforum@thisisnotmyrealemail.com> writes:
Fleck Jean-Julien wrote:
How i can convert this proper way?
Try without the quotes
Regexp.new(/regexp/i)
=> /regexp/i
Cheers,
I cannot do this without quotes - i need get it from string. Only thing
i have is "/regexp/i" string.
string="/regexp/i"
Regexp.new(eval(string))
2009/8/21 Joao Silva <rubyforum@thisisnotmyrealemail.com>:
--
__Pascal Bourguignon__
Sorry, it gave me what I expected, and Ruby is usually intuitive, so I
thought I got it right. This class, however, is not. I had to learn some of
it's internal logic to figure it out. (they define constants for each flag,
these constants are integers, you then have to add the values of the
constants of all the flags together to get the new options value)
class String
return nil unless self.strip.match(/\A\/(.*)\/(.*)\Z/mx)
regexp , flags = $1 , $2
return nil if !regexp || flags =~ /[^xim]/m
x = /x/.match(flags) && Regexp::EXTENDED
i = /i/.match(flags) && Regexp::IGNORECASE
m = /m/.match(flags) && Regexp::MULTILINE
Regexp.new regexp , [x,i,m].inject(0){|a,f| f ? a+f : a }
end
end
#fail cases
"regexp".to_r # => nil
"regexp/i".to_r # => nil
"/regexp/mk".to_r # => nil
<<-ENDOFSTRING.to_r # => nil
hello rEG
world exP
ENDOFSTRING
"/regexp/mk
hello rEG
world exP".to_r # => nil
#pass cases
"/reg/".to_r # => /reg/
" /reg/x ".to_r # => /reg/x
"/reg.*?exp/m".to_r # => /reg.*?exp/m
"/regexp/x".to_r # => /regexp/x
"/abc
def
ghi/xi".to_r # => /abc
# def
# ghi/ix
"//".to_r # => //
"/abc/i".to_r # => /abc/i
"/abc/x".to_r # => /abc/x
"/abc/m".to_r # => /abc/m
"/abc/ix".to_r # => /abc/ix
"/abc/im".to_r # => /abc/mi
"/abc/xm".to_r # => /abc/mx
"/abc/ixm".to_r # => /abc/mix
"/abc/mxi".to_r # => /abc/mix
On Fri, Aug 21, 2009 at 5:27 AM, 7stud -- <bbxx789_05ss@yahoo.com> wrote:
Josh Cheek wrote:
> class String
> def to_r
> Regexp.new(*strip.match(/\/(.*)\/(.*)/)[1,2])
> end
> end
>
> "/regexp/i".to_r # => /regexp/i
>Doesn't work in this case:
str = "/reg.*?exp/m"
test_str =<<ENDOFSTRING
hello rEG
world exP
ENDOFSTRING...nor when there is more than one flag.
--
Posted via http://www.ruby-forum.com/\.
Pascal J. Bourguignon wrote:
Joao Silva <rubyforum@thisisnotmyrealemail.com> writes:
Cheers,
I cannot do this without quotes - i need get it from string. Only thing
i have is "/regexp/i" string.string="/regexp/i"
Regexp.new(eval(string))
I tried this, but it's totally unsafe way (these strings are provided by
user).
--
Posted via http://www.ruby-forum.com/\.
Eval is a mighty tool for a tiny task
option = str[-1] # Ruby 1.9, use [-1,1] in 1.8
Regexp::new( str[1..-3], option )
HTH
R
On Fri, Aug 21, 2009 at 12:00 PM, Pascal J. Bourguignon<pjb@informatimago.com> wrote:
Joao Silva <rubyforum@thisisnotmyrealemail.com> writes:
Fleck Jean-Julien wrote:
2009/8/21 Joao Silva <rubyforum@thisisnotmyrealemail.com>:
How i can convert this proper way?
Try without the quotes
Regexp.new(/regexp/i)
=> /regexp/i
Cheers,
I cannot do this without quotes - i need get it from string. Only thing
i have is "/regexp/i" string.string="/regexp/i"
Regexp.new(eval(string))--
__Pascal Bourguignon__
--
module Kernel
alias_method :λ, :lambda
end
"Regexp.new" is superfluous:
irb(main):002:0> eval("/regexp/i").class
=> Regexp
irb(main):003:0>
Cheers
robert
2009/8/21 Pascal J. Bourguignon <pjb@informatimago.com>:
Joao Silva <rubyforum@thisisnotmyrealemail.com> writes:
Fleck Jean-Julien wrote:
2009/8/21 Joao Silva <rubyforum@thisisnotmyrealemail.com>:
How i can convert this proper way?
Try without the quotes
Regexp.new(/regexp/i)
=> /regexp/i
Cheers,
I cannot do this without quotes - i need get it from string. Only thing
i have is "/regexp/i" string.string="/regexp/i"
Regexp.new(eval(string))
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
Josh Cheek wrote:
Sorry, it gave me what I expected, and Ruby is usually intuitive, so I
thought I got it right.
Mine solution has problems too--for the same reason. It needs something
like this:
arg_two = nil if arg_two == 0
regex = Regexp.new(pattern, arg_two)
--
Posted via http://www.ruby-forum.com/\.
If the strings are provided by an untrusted source, don't use any solution that uses eval().
Instead, use a solution that recognizes the string contains a regexp and then uses a regexp constructor after pulling the relevant data out of the string. Something along the lines of:
def parse_input(str)
if md = %r{^/(.*)+/(.*)*$}.match(str)
#it's a regexp
pattern = md[1]
if md[2]
# deal with the flags
flags = deal_with(md[2]
end
Regexp.new(pattern, flags)
else
...
end
end
Ben
On Aug 21, 2009, at 06:04, Joao Silva wrote:
I tried this, but it's totally unsafe way (these strings are provided by
user).
Ben Giddings wrote in post #844686:
If the strings are provided by an untrusted source, don't use any
solution that uses eval().
Yes.
Instead, use a solution that recognizes the string contains a regexp
and then uses a regexp constructor after pulling the relevant data out
of the string. Something along the lines of:def parse_input(str)
if md = %r{^/(.*)+/(.*)*$}.match(str)
Nice try, but that regexp isn't safe. I think Ruby's design decision
here was a bad one. In Ruby, you need \A to match only at the start of
string, and \z to match only at the end of string (whereas you might
expect ^ and $ to mean that)
Also, I'd suggest that repeated capture groups are a bit confusing, e.g.
where you write (.*)+ when (.*) by itself would be fine. Because * is
greedy, .* will capture as much as possible so the + will only repeat
once.
Anyway, here's a trick for handling the flags: note that /foo/i can be
represented as (?i:foo)
raise "Invalid regexp" unless %r{\A/(.*)/([mix]*)\z} =~ str
Regexp.new("(?#{$2}:#{$1})")
--
Posted via http://www.ruby-forum.com/\.