# How to convert a "normal" searchstring into regexp

**URL:** <https://www.ruby-forum.com/t/how-to-convert-a-normal-searchstring-into-regexp/175006>\
**Category:** Ruby\
**Created:** [September 5, 2009, 6:05pm UTC](https://www.ruby-forum.com/t/how-to-convert-a-normal-searchstring-into-regexp/175006 "2009-09-05T18:05:35Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![noxx000](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/b77776/32.png) [@noxx000](https://www.ruby-forum.com/u/noxx000)\
**Post date:** [September 5, 2009, 6:05pm UTC](https://www.ruby-forum.com/t/how-to-convert-a-normal-searchstring-into-regexp/175006/1 "2009-09-05T18:05:35Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![noxx000](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/b77776/32.png) [@noxx000](https://www.ruby-forum.com/u/noxx000)\
**Post date:** [September 7, 2009, 10:42am UTC](https://www.ruby-forum.com/t/how-to-convert-a-normal-searchstring-into-regexp/175006/2 "2009-09-07T10:42:07Z")

</div>

this seems to do the trick:  
[http://pastie.org/608326](http://pastie.org/608326)  
I haven’t tested it much though…

Greetz!

2009/9/5 Kioko – [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![noxx000](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/b77776/32.png) [@noxx000](https://www.ruby-forum.com/u/noxx000)\
**Post date:** [September 7, 2009, 5:23pm UTC](https://www.ruby-forum.com/t/how-to-convert-a-normal-searchstring-into-regexp/175006/3 "2009-09-07T17:23:07Z")

</div>

2009/9/7 Fabian S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> this seems to do the trick:  
> [http://pastie.org/608326](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

---

<div class="post-metadata">

**Author:** ![noxx000](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/b77776/32.png) [@noxx000](https://www.ruby-forum.com/u/noxx000)\
**Post date:** [September 7, 2009, 6:12pm UTC](https://www.ruby-forum.com/t/how-to-convert-a-normal-searchstring-into-regexp/175006/4 "2009-09-07T18:12:29Z")

</div>

Robert K. wrote:

> this seems to do the trick:  
> [http://pastie.org/608326](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.

---

<div class="post-metadata">

**Author:** ![noxx000](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/b77776/32.png) [@noxx000](https://www.ruby-forum.com/u/noxx000)\
**Post date:** [September 7, 2009, 6:28pm UTC](https://www.ruby-forum.com/t/how-to-convert-a-normal-searchstring-into-regexp/175006/5 "2009-09-07T18:28:06Z")

</div>

On 07.09.2009 18:12, Kioko – wrote:

> > “/^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

---

<div class="post-metadata">

**Author:** ![noxx000](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/b77776/32.png) [@noxx000](https://www.ruby-forum.com/u/noxx000)\
**Post date:** [September 8, 2009, 1:23pm UTC](https://www.ruby-forum.com/t/how-to-convert-a-normal-searchstring-into-regexp/175006/6 "2009-09-08T13:23:37Z")

</div>

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!

2009/9/7 Kioko – [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![noxx000](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/b77776/32.png) [@noxx000](https://www.ruby-forum.com/u/noxx000)\
**Post date:** [September 7, 2009, 7:45pm UTC](https://www.ruby-forum.com/t/how-to-convert-a-normal-searchstring-into-regexp/175006/7 "2009-09-07T19:45:45Z")

</div>

Robert K. wrote:

> 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!

---

<div class="post-metadata">

**Author:** ![noxx000](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/b77776/32.png) [@noxx000](https://www.ruby-forum.com/u/noxx000)\
**Post date:** [September 8, 2009, 1:42pm UTC](https://www.ruby-forum.com/t/how-to-convert-a-normal-searchstring-into-regexp/175006/8 "2009-09-08T13:42:56Z")

</div>

2009/9/8 Fabian S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 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

---

<div class="post-metadata">

**Author:** ![noxx000](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/b77776/32.png) [@noxx000](https://www.ruby-forum.com/u/noxx000)\
**Post date:** [September 8, 2009, 4:23pm UTC](https://www.ruby-forum.com/t/how-to-convert-a-normal-searchstring-into-regexp/175006/9 "2009-09-08T16:23:19Z")

</div>

> 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!
