Perl 5.8 RE for fixed string with an optional colon terminated prefix

Discussion in 'Perl Misc' started by RedGrittyBrick, Apr 8, 2010.

  1. I need to match fixed string FOO with an optional : terminated prefix

    This doesn't work because the RE matches notFOO

    for my $x (qw(FOO xxx:FOO yyy.FOO BAR notFOO FOOM)) {
    if ($x =~ /^[^:]*:?FOO$/) {
    print "Matched $x\n";
    } else {
    print "- $x\n";
    }
    }

    Actual output:

    Matched FOO
    Matched xxx:FOO
    Matched yyy.FOO
    - BAR
    Matched notFOO
    - FOOM

    Desired output:

    Matched FOO
    Matched xxx:FOO
    Matched yyy.FOO
    - BAR
    - notFOO
    - FOOM

    xxx and yyy are just examples of \w+ excluding ':'

    I've glanced at perlretut but would appreciate a clue.

    --
    RGB
     
    RedGrittyBrick, Apr 8, 2010
    #1
    1. Advertising

  2. Re: Perl 5.8 RE for fixed string with an optional colon terminatedprefix

    On 08/04/2010 15:39, RedGrittyBrick wrote:
    > I need to match fixed string FOO with an optional : terminated prefix
    >
    > This doesn't work because the RE matches notFOO
    >
    > for my $x (qw(FOO xxx:FOO yyy.FOO BAR notFOO FOOM)) {
    > if ($x =~ /^[^:]*:?FOO$/) {


    if ($x =~ /^[^:]*:?\bFOO$/) {

    > print "Matched $x\n";
    > } else {
    > print "- $x\n";
    > }
    > }
    >


    I knew I'd end up feeling stupid :)

    --
    RGB
     
    RedGrittyBrick, Apr 8, 2010
    #2
    1. Advertising

  3. Re: Perl 5.8 RE for fixed string with an optional colon terminatedprefix

    On Thu, 8 Apr 2010, RedGrittyBrick wrote:

    > if ($x =~ /^[^:]*:?\bFOO$/) {


    That will still independetly check for optional [^:]* and optional :
    letting ,,,FOO pass. What you mean is probably /^([^:]+:)?\bFOO$/.
    Here I assumed that the part before the colon is nonempty if the colon is
    present.

    --
    Helmut Richter
     
    Helmut Richter, Apr 8, 2010
    #3
  4. Re: Perl 5.8 RE for fixed string with an optional colon terminatedprefix

    On 08/04/2010 16:22, Helmut Richter wrote:
    > On Thu, 8 Apr 2010, RedGrittyBrick wrote:
    >
    >> if ($x =~ /^[^:]*:?\bFOO$/) {

    >
    > That will still independetly check for optional [^:]* and optional :
    > letting ,,,FOO pass. What you mean is probably /^([^:]+:)?\bFOO$/.


    Ah yes.

    > Here I assumed that the part before the colon is nonempty if the colon is
    > present.


    Your assumption is correct.

    Thanks

    --
    RGB
     
    RedGrittyBrick, Apr 8, 2010
    #4
  5. RedGrittyBrick

    Uri Guttman Guest

    >>>>> "HR" == Helmut Richter <> writes:

    HR> On Thu, 8 Apr 2010, RedGrittyBrick wrote:
    >> if ($x =~ /^[^:]*:?\bFOO$/) {


    HR> That will still independetly check for optional [^:]* and optional
    HR> : letting ,,,FOO pass. What you mean is probably
    HR> /^([^:]+:)?\bFOO$/. Here I assumed that the part before the colon
    HR> is nonempty if the colon is present.

    i was going to suggest the grouping too. he says the whole prefix is
    optional but he made the parts seperately optional instead. but now you
    don't need the \b since if whole prefix is matched and it ends with :
    and then sees FOO which means it always has a word boundary. also make
    the group non-grabbing to speed it up unless he needs to grab the
    prefix.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
     
    Uri Guttman, Apr 8, 2010
    #5
  6. RedGrittyBrick

    Guest

    On Thu, 08 Apr 2010 15:39:04 +0100, RedGrittyBrick <> wrote:

    >I need to match fixed string FOO with an optional : terminated prefix
    >
    >This doesn't work because the RE matches notFOO
    >
    >for my $x (qw(FOO xxx:FOO yyy.FOO BAR notFOO FOOM)) {
    > if ($x =~ /^[^:]*:?FOO$/) {

    ^^^^^^^^
    This can't be generalized to be put together without alternation.
    ^ and [^:]*:? need to be alternatives as a prefix to FOO
    Because it makes you have to say [^:]*:? and the quantifiers
    * ? make posibile any char not :* zero or more times then :?
    zero or one time.

    This makes it too particular in its need to find : and results
    in everything else not : getting by and matching. Even if you used
    [.:] it wouldn't work.

    From your own description, you positively are looking for only
    2 things to match:

    1. FOO all by itself
    2. FOO prefixed by anything plus : or .

    Thats the way you have to write the regexp.
    Lets also asume that 1 and 2 above can be surrounded by optional
    whitespace:

    1. FOO all by itself
    / ^ \s* FOO \s* $ /x
    2. FOO prefixed by anything plus : or .
    / .+[.:] FOO \s* $ /xs

    Join them together via factoring:

    / (?: ^\s* | .+[.:] ) FOO \s* $/xs

    > print "Matched $x\n";
    > } else {
    > print "- $x\n";
    > }
    >}
    >


    Matched () FOO
    Matched (xxx:) xxx:FOO
    Matched (yyy.) yyy.FOO
    - BAR
    - notFOO
    - FOOM

    -----------------------
    use strict;
    use warnings;

    for my $x (qw(FOO xxx:FOO yyy.FOO BAR notFOO FOOM)) {
    if ($x =~ / ( ^\s* | .+[.:] ) FOO \s* $/xs) {
    print "Matched ($1) $x\n";
    } else {
    print "- $x\n";
    }
    }
    __END__

    -sln
     
    , Apr 8, 2010
    #6
  7. RedGrittyBrick

    Guest

    On Thu, 08 Apr 2010 15:39:04 +0100, RedGrittyBrick <> wrote:

    >I need to match fixed string FOO with an optional : terminated prefix
    >
    >This doesn't work because the RE matches notFOO
    >
    >for my $x (qw(FOO xxx:FOO yyy.FOO BAR notFOO FOOM)) {
    > if ($x =~ /^[^:]*:?FOO$/) {
    > print "Matched $x\n";
    > } else {
    > print "- $x\n";
    > }
    >}
    >


    Another possiblity:

    Avoid having to describe everything preceeding FOO.
    And, if you don't care about captureing all before FOO,
    this should speed up the search/matching if you have
    alot to parse.

    use strict;
    use warnings;

    for my $x (qw(FOO :FOO xxx:FOO .FOO yyy.FOO BAR notFOO FOOM)) {
    if ($x =~ / (?: ^ | (?<=[:.]) ) \s* FOO \s* $ /x) {
    print "Matched $x\n";
    print "Matched ($1) $x\n";
    } else {
    print "- $x\n";
    }
    }
    ---------------

    Matched FOO
    Matched :FOO
    Matched xxx:FOO
    Matched .FOO
    Matched yyy.FOO
    - BAR
    - notFOO
    - FOOM
     
    , Apr 8, 2010
    #7
  8. Re: Perl 5.8 RE for fixed string with an optional colon terminatedprefix

    On Thu, 8 Apr 2010, Uri Guttman wrote:

    > HR> On Thu, 8 Apr 2010, RedGrittyBrick wrote:
    > >> if ($x =~ /^[^:]*:?\bFOO$/) {


    > i was going to suggest the grouping too. he says the whole prefix is
    > optional but he made the parts seperately optional instead. but now you
    > don't need the \b


    Yes, of course. It remained from cut 'n paste.

    --
    Helmut Richter
     
    Helmut Richter, Apr 8, 2010
    #8
  9. RedGrittyBrick

    Guest

    On Thu, 8 Apr 2010 17:22:48 +0200, Helmut Richter <> wrote:

    >On Thu, 8 Apr 2010, RedGrittyBrick wrote:
    >
    >> if ($x =~ /^[^:]*:?\bFOO$/) {

    >
    >That will still independetly check for optional [^:]* and optional :
    >letting ,,,FOO pass. What you mean is probably /^([^:]+:)?\bFOO$/.
    >Here I assumed that the part before the colon is nonempty if the colon is
    >present.



    this - /^([^:]+:)?\bFOO$/

    Indeed, grouping the the optional [^:]* and optional :
    into a ()? took care of [^:]* letting ,,,FOO pass

    However, by doing that, you don't let "prefix.FOO" pass.
    This is why he had the :? independently optional so that

    ^[^:]*:?\bFOO$ would match 'prefix.FOO'

    The \b protects the '.FOO' and the 'FOO' at the same time.
    where [^:]*:? specifically matches 'prefix:FOO' and just so
    happens : is compliant with \b and redundant.

    Grouping changes the condition. Now \b won't find '.FOO'
    because the search never consumes a '.'

    This /^([^:]+:)?\bFOO$/ regexp at best is bloviated and redundant,
    at worst will not match the conditions.

    -sln
     
    , Apr 8, 2010
    #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. Tim Tyler
    Replies:
    36
    Views:
    1,528
    Darryl L. Pierce
    Dec 10, 2004
  2. VanOrton
    Replies:
    2
    Views:
    2,598
    VanOrton
    Nov 30, 2005
  3. Michael
    Replies:
    21
    Views:
    1,398
    Robert Kern
    Sep 15, 2006
  4. Chris  Chiasson
    Replies:
    6
    Views:
    652
    Richard Tobin
    Nov 14, 2006
  5. khany
    Replies:
    6
    Views:
    1,166
    Dave Angel
    Oct 19, 2009
Loading...

Share This Page