How to convert a "normal" searchstring into regexp

K

Kioko --

Hi there,
I'm really new to Ruby and I hope I didn't overlook something while
searching through forums and docs but I got a small problem which I
can't solve myself... :(

As many users aren't familiar with regexp I need something different to
match a string.

e.g. I would like
"my.li??le.searchstri*g\?" to match against "my.little.searchstring?"
(so input is a "normal" searchstring which would be familiar to all
users)

I didn't find a method which do some matching work except Regexp's match
My solution now was to "convert" the searchstring into a regexp like
"^my\.li..le\.searchstri.*g\?$"

However, after hours of working, I was unable to code something like
that.

My idea was to "Regexp.escape(searchstring)" it first and than replace
"\?" with "." and "\*" with ".*" and so on (horrible, isn't it?)

It would really appreciate it, if someone could give me some hints how
to solve it more easier or even if there is something in Ruby I didn't
see yet.

Thanks for reading.
Noxx
 
R

Robert Klemme

2009/9/7 Fabian Streitel said:
this seems to do the trick:
http://pastie.org/608326
I haven't tested it much though...

A simple solution:

class String
def to_glob
Regexp.new(gsub(%r{(?<!\\)[*?.]}) do |match|
GLOB_REPLACE.fetch(match, match)
end)
end

private
GLOB_REPLACE = {
"." => "\\.",
"*" => ".*",
"?" => "."
}
end

irb(main):015:0> "foo*.b?r".to_glob
=> /foo.*\.b.r/

Of course, this is not complete, as other regexp meta characters need
to be dealt with. And you need 1.8.7 or 1.9.* for the negative
lookbehind to work IIRC.

Kind regards

robert
 
K

Kioko --

Robert said:
this seems to do the trick:
http://pastie.org/608326
I haven't tested it much though...

Thanks, but unfurtunatly it seems to not work correctly.
As I tested it with my example string "my.li??le.searchstri*g\?" the
result was
"/^..my\\.li.*le\\.searchstri\\?g$/".
(to compare it easier, it should be something like:
"/^my\.li..le\.searchstri.*g\?$/"

robert, thank you too but also with your script I get an error if I try
to run it:
undefined (?...) sequence: /(?<!\\)[*?.]/

As I'm new to ruby I don't know if it's just me... you tried it too and
didn't get an error.
My version: "ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]"
installed over apt (ubuntu)

However, thank you very much for your replies and your time.
 
R

Robert Klemme

Robert said:
this seems to do the trick:
http://pastie.org/608326
I haven't tested it much though...

Thanks, but unfurtunatly it seems to not work correctly.
As I tested it with my example string "my.li??le.searchstri*g\?" the
result was
"/^..my\\.li.*le\\.searchstri\\?g$/".
(to compare it easier, it should be something like:
"/^my\.li..le\.searchstri.*g\?$/"

robert, thank you too but also with your script I get an error if I try
to run it:
undefined (?...) sequence: /(?<!\\)[*?.]/

As I'm new to ruby I don't know if it's just me... you tried it too and
didn't get an error.
My version: "ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]"
installed over apt (ubuntu)

It's the Ruby version. You need Oniguruma which is default in 1.9 and I
believe it is just optional in 1.8.7. I tested with 1.9.1. Sorry for
the confusion.

You can probably make it work with something like this

# untested
class String
def to_glob
Regexp.new(gsub(%r{(?<!\\)[*?.]}) do |match|
/\\\z/ =~ $` ? match : GLOB_REPLACE.fetch(match, match)
end)
end

private
GLOB_REPLACE = {
"." => "\\.",
"*" => ".*",
"?" => "."
}
end
However, thank you very much for your replies and your time.

You're welcome!

Kind regards

robert
 
K

Kioko --

Robert said:
It's the Ruby version. You need Oniguruma which is default in 1.9 and I
believe it is just optional in 1.8.7. I tested with 1.9.1. Sorry for
the confusion.

ok.. after some more deeper investigation I found that I got 1.8.7 and
1.9.0.2 installed at the same time.
After purging the old version, reinstalling 1.9, getting even more
errors about libraries, purging and reinstalling 1.9 a second time I
found a problem in my libruby1.9.so so I purged it too and reinstalled
it.

Now it works great and I'm very happy :)

Thank you very much!
 
F

Fabian Streitel

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

that would probably be a good idea for a gem, although I'd
do it with a real parser and tokenizer, as that offers much more
safety than regexps and would also be backwards compatible with 1.8.*

Greetz!
 
R

Robert Klemme

2009/9/8 Fabian Streitel said:
that would probably be a good idea for a gem, although I'd
do it with a real parser and tokenizer, as that offers much more
safety than regexps and would also be backwards compatible with 1.8.*

As far as I can see you only need a scanner here - there is no CFG
that you would have to parse. So why build something that complex
when there's a simpler (and probably also faster) solution?

Cheers

robert
 
F

Fabian Streitel

[Note: parts of this message were removed to make it a legal post.]
As far as I can see you only need a scanner here - there is no CFG
that you would have to parse. So why build something that complex
when there's a simpler (and probably also faster) solution?

well that was just an idea thrown in. it's not like i sketched it out on
chalkboard and wrote a specification.

Greetz!
 

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

Members online

No members online now.

Forum statistics

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

Latest Threads

Top