How to convert a "normal" searchstring into regexp

Discussion in 'Ruby' started by Kioko --, Sep 5, 2009.

  1. Kioko --

    Kioko -- Guest

    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
    --
    Posted via http://www.ruby-forum.com/.
     
    Kioko --, Sep 5, 2009
    #1
    1. Advertising

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

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

    Greetz!

    2009/9/5 Kioko -- <>

    > 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)
    >
    >
     
    Fabian Streitel, Sep 7, 2009
    #2
    1. Advertising

  3. 2009/9/7 Fabian Streitel <>:
    > 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

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Sep 7, 2009
    #3
  4. Kioko --

    Kioko -- Guest

    Robert Klemme wrote:
    > 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.
    --
    Posted via http://www.ruby-forum.com/.
     
    Kioko --, Sep 7, 2009
    #4
  5. On 07.09.2009 18:12, Kioko -- wrote:
    > Robert Klemme wrote:
    >> 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

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Sep 7, 2009
    #5
  6. Kioko --

    Kioko -- Guest

    Robert Klemme 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!
    --
    Posted via http://www.ruby-forum.com/.
     
    Kioko --, Sep 7, 2009
    #6
  7. [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!

    2009/9/7 Kioko -- <>

    > Robert Klemme 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!
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >
     
    Fabian Streitel, Sep 8, 2009
    #7
  8. 2009/9/8 Fabian Streitel <>:
    > 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

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Sep 8, 2009
    #8
  9. [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!
     
    Fabian Streitel, Sep 8, 2009
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Guest
    Replies:
    2
    Views:
    773
    Guest
    Jun 20, 2007
  2. Johannes Bauer

    Convert numpy.ndarray into "normal" array

    Johannes Bauer, Apr 24, 2009, in forum: Python
    Replies:
    4
    Views:
    1,772
    Piet van Oostrum
    Apr 25, 2009
  3. Greg Hurrell
    Replies:
    4
    Views:
    172
    James Edward Gray II
    Feb 14, 2007
  4. Joao Silva
    Replies:
    16
    Views:
    391
    7stud --
    Aug 21, 2009
  5. williamroy
    Replies:
    1
    Views:
    143
    Joshie Surber
    Nov 18, 2005
Loading...

Share This Page