[regexp] How to convert string "/regexp/i" to /regexp/i - ?

J

Joao Silva

When i try to use:
=> /\/regexp\/i/

But it's not what i want - i need:

/regexp/i

:-(

How i can convert this proper way?
 
F

Fleck Jean-Julien

2009/8/21 Joao Silva said:
When i try to use:

=3D> /\/regexp\/i/

But it's not what i want - i need:

/regexp/i

:-(

How i can convert this proper way?

Try without the quotes
=3D> /regexp/i

Cheers,

--=20
JJ Fleck
PCSI1 Lyc=E9e Kleber
 
J

Justin Collins

Joao said:
When i try to use:


=> /\/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
 
J

Joao Silva

Fleck said:
Try without the quotes

=> /regexp/i

Cheers,

I cannot do this without quotes - i need get it from string. Only thing
i have is "/regexp/i" string.

Thanks!
 
M

Michal Zacik

Regexp.new(/regexp/i)

Joao said:
When i try to use:


=> /\/regexp\/i/

But it's not what i want - i need:

/regexp/i

:-(

How i can convert this proper way?
 
J

Justin Collins

Justin said:
Joao said:
When i try to use:


=> /\/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
 
P

Pascal J. Bourguignon

Joao Silva said:
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))
 
R

Robert Dober

string=3D"/regexp/i"
Regexp.new(eval(string))
Eval is a mighty tool for a tiny task

option =3D str[-1] # Ruby 1.9, use [-1,1] in 1.8

Regexp::new( str[1..-3], option )

HTH
R


--=20
module Kernel
alias_method :=EB, :lambda
end
 
7

7stud --

Joao said:
When i try to use:

=> /\/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
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

class String
def to_r
Regexp.new(*strip.match(/\/(.*)\/(.*)/)[1,2])
end
end

"/regexp/i".to_r # => /regexp/i


=> /\/regexp\/i/

But it's not what i want - i need:

/regexp/i

:-(

How i can convert this proper way?[/QUOTE]
 
7

7stud --

Josh said:
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.
 
R

Robert Klemme

2009/8/21 Pascal J. Bourguignon said:
string="/regexp/i"
Regexp.new(eval(string))

"Regexp.new" is superfluous:

irb(main):002:0> eval("/regexp/i").class
=> Regexp
irb(main):003:0>

Cheers

robert
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

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





Josh said:
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.
 
B

Ben Giddings

I tried this, but it's totally unsafe way (these strings are
provided by
user).

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
 
7

7stud --

Josh said:
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)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top