partially matching a regexp

Discussion in 'Perl Misc' started by Thomas Koenig, Aug 5, 2004.

  1. Assume I have a regexp, /^(hello)|(goodbye)$/ for example.

    I want to see wether a particular string matches part of that
    particular regexp, so "", "h", "he", "hel", "hell", "hello", "g",
    "go", "goo" "good", "goodb", "goodby" and "goodbye" would be ok,
    and anything else wouldn't.

    I could hand-craft this example easily enough, but it grows
    tedious and error-prone for more general regular expressions,
    and automation would be much preferred.

    Ideas?
     
    Thomas Koenig, Aug 5, 2004
    #1
    1. Advertisements

  2. Take a look at the source of File::Stream. A very similar problem is
    solved in File::Stream::find and the solution to that problem could
    probably be easily be adapted (simplified!) to solve your problem.
     
    Brian McCauley, Aug 5, 2004
    #2
    1. Advertisements

  3. Something like:

    if(test($input,"hello") || test($input,"goodbye"))
    {
    # stuff
    }

    sub test
    {
    my($s1,$s2)[email protected]_;
    for my $len(0..length($s2))
    {
    return 1 if(substr($s2,0,$len) eq $s1);
    }
    return 0;
    }
     
    Andrew Palmer, Aug 6, 2004
    #3
  4. Sounds as if 'index' (perldoc -f index) might be easier and
    in some cases faster than a regex:


    my $substring = ...
    for ( qw/hello goodbye/ ) {
    print "$substring matched $_\n" if index($_, $substring) != -1;
    }
     
    Charles DeRykus, Aug 7, 2004
    #4
  5. Thomas Koenig

    Jay Tilton Guest

    : Assume I have a regexp, /^(hello)|(goodbye)$/ for example.
    :
    : I want to see wether a particular string matches part of that
    : particular regexp, so "", "h", "he", "hel", "hell", "hello", "g",
    : "go", "goo" "good", "goodb", "goodby" and "goodbye" would be ok,
    : and anything else wouldn't.
    :
    : I could hand-craft this example easily enough, but it grows
    : tedious and error-prone for more general regular expressions,
    : and automation would be much preferred.

    This sounds like an opportunity to abuse Perl's
    (?(condition)pattern) regex feature.

    #!/perl
    use strict;
    use warnings;

    my $pat_h = buildpattern( 'hello' );
    my $pat_g = buildpattern( 'goodbye' );

    while(<DATA> ) {
    chomp;
    print "matched '$1' in '$_'\n"
    if /$pat_h/ or /$pat_g/;
    }

    sub buildpattern {
    my @lets = $_[0] =~ /./g;
    my $pat;
    for( 0 .. $#lets ) {
    $pat .= $_ == 0 ? $lets[$_] :
    $_ == 1 ? "($lets[$_])?" :
    "((?($_)$lets[$_]))?"
    }
    return qr/(^$pat)/;
    }

    __DATA__
    hello
    helpme
    haveaniceday
    goodbye
    goodgrief
    gabbagabbahey
     
    Jay Tilton, Aug 8, 2004
    #5
  6. I'm currently doing that, and trying to understand what YAPE::regexp
    does (which isn't too easy :)

    If I get anywhere, I'll let the newsgroup know.
     
    Thomas Koenig, Aug 9, 2004
    #6
  7. I'd suggest switching over to Regexp::parser. I'm hoping to get
    Regexp::Explain out in the near future.

    --
    Jeff "japhy" Pinyan % How can we ever be the sold short or
    RPI Acacia Brother #734 % the cheated, we who for every service
    RPI Corporation Secretary % have long ago been overpaid?
    http://japhy.perlmonk.org/ %
    http://www.perlmonks.org/ % -- Meister Eckhart
     
    Jeff 'japhy' Pinyan, Aug 9, 2004
    #7
  8. Clearly the above code is retarded. The equivalent using index() is simply:

    if(index("hello",$input)==0 || index("goodbye",$input)==0)
    {
    # stuff
    }

    The regex tokenizing modules seem unnecessary for the example you posted. Is
    your actual test significantly more complicated?
     
    Andrew Palmer, Aug 11, 2004
    #8
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.