perl pattern matching

Discussion in 'OT Technology' started by purebad, Jan 30, 2007.

  1. purebad

    purebad I don't need your approval, right?

    Joined:
    Aug 25, 2006
    Messages:
    4,376
    Likes Received:
    0
    Location:
    Smyrna, GA
    there are plenty of resources with pattern matching information, but I'm having a hard time seeing how to match a patter for a date. I need it to be [1-12]/[1-31]/[2006-2007]

    so would it be something like this?

    $date =~ m/[1-12]+\/+[1-31]+\/+[2006-2007]/;
     
    Last edited: Jan 30, 2007
  2. Joe_Cool

    Joe_Cool Never trust a woman or a government. Moderator

    Joined:
    Jun 30, 2003
    Messages:
    299,246
    Likes Received:
    537
    Regular expressions match literal text; they don't match numerically.

    For example, [1-31] will match 1, 2, or 3. It will fail on 5 or 7.


    Try something more like this:

    m/(1[012]|0[1-9])\/(0[1-9]|[12][0-9]|3[01])\/200[67]/

    That should match mm/dd/yyyy

    (1[012]|0[1-9]) matches one of:
    1[012]: 10, 11, or 12
    OR
    0[1-9]: 01, 02, ... 08, 09 You can drop the leading zero if you don't want it.

    (0[1-9]|[12][0-9]|3[01]) matches one of:
    0[1-9]: 01 - 09 Again, you can drop the zero if you don't want it.
    OR
    [12][0-9]: 10-19, 20-29
    OR
    3[01]: 30, 31

    200[67] matches (obviously) either 2006 or 2007.

    Hope that helps.
     
    Last edited: Jan 30, 2007
  3. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    God, I love perl.

    What are you actually trying to accomplish?

    $foo =~ \d+\/\d+\/d+
     
  4. Joe_Cool

    Joe_Cool Never trust a woman or a government. Moderator

    Joined:
    Jun 30, 2003
    Messages:
    299,246
    Likes Received:
    537
    81234187253182538561281/087209387509238750399/6896198236481725476128365871

    FTW :mamoru:
     
  5. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    eh, ok:

    \d{1,2}\/\d{1,2}\/\d{2,4}
     
  6. purebad

    purebad I don't need your approval, right?

    Joined:
    Aug 25, 2006
    Messages:
    4,376
    Likes Received:
    0
    Location:
    Smyrna, GA
    :bowdown: thanks, cleared up my misconceptions.
     
  7. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    Are you trying to validate input from a form?
     
  8. Joe_Cool

    Joe_Cool Never trust a woman or a government. Moderator

    Joined:
    Jun 30, 2003
    Messages:
    299,246
    Likes Received:
    537
    Keep in mind that won't do everything for you. It won't fail on Feb 31, for example. :o
     
  9. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    Actually, can you write a regex that DOES fail on Feb 31? :)
     
  10. Joe_Cool

    Joe_Cool Never trust a woman or a government. Moderator

    Joined:
    Jun 30, 2003
    Messages:
    299,246
    Likes Received:
    537
    I'm sure it can be done.

    I'm equally sure that I can't do it. :mamoru: At least not in a reasonable amount of time. :o
     
  11. Joe_Cool

    Joe_Cool Never trust a woman or a government. Moderator

    Joined:
    Jun 30, 2003
    Messages:
    299,246
    Likes Received:
    537
    Actually, yes I can, but it'd be ugly. I don't know an elegant way to do it.
     
    Last edited: Jan 30, 2007
  12. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    LAMER

    Yeah, me neither. You'd just have to or it... actually.

    1\/[1-31]|2\/[0-28]|...

    would take care of the days in month problem.
     
  13. Joe_Cool

    Joe_Cool Never trust a woman or a government. Moderator

    Joined:
    Jun 30, 2003
    Messages:
    299,246
    Likes Received:
    537
    Something long and unwieldy like this:

    ((0?[13478]|1[02])\/(0?[1-9]|[12][0-9]|3[01])|((0?[469)11)\/(0?[1-9]|[12][0-9]|30)|(0?2\/(0?[1-9]|[12][0-9])))\/200[67]

    should work, but I'm betting I messed up the parentheses. :mamoru:
     
  14. Joe_Cool

    Joe_Cool Never trust a woman or a government. Moderator

    Joined:
    Jun 30, 2003
    Messages:
    299,246
    Likes Received:
    537
    It treats mm/dd as an entity and handles it differently for the 31, 30, and 29 day months, then adds on the year at the end. :o
     
  15. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    The parenthesis will just slow it down, as it will store variables for re-use is you s///. You can so s/(foo)(bar)/$2$1 and you get barfoo.

    If you don't use em, I don't think it breaks em. Just slows em.
     
  16. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    Oh, and dude... [1-31] matches any number between one and 31. Its not by character in that case. I just checked man perlre
     
  17. Joe_Cool

    Joe_Cool Never trust a woman or a government. Moderator

    Joined:
    Jun 30, 2003
    Messages:
    299,246
    Likes Received:
    537
    :nono: Not \(\) (that stores the match for later use), just () to group the OR clauses.
     
  18. Joe_Cool

    Joe_Cool Never trust a woman or a government. Moderator

    Joined:
    Jun 30, 2003
    Messages:
    299,246
    Likes Received:
    537
    I just tested it out in perl 5:

    Code:
    temp.pl:
    #!/usr/bin/perl
    [b]$a="5";[/b]
    if($a =~ m/[1-31]/)
    {
    print "TRUE\n\n";
    }
    else
    {
    print "FALSE\n\n";
    }
    
    
    
    $ perl temp.pl
    [b]FALSE[/b]
    
    $
    Code:
    temp1.pl:
    #!/usr/bin/perl
    [b]$a="3";[/b]
    if($a =~ m/[1-31]/)
    {
    print "TRUE\n\n";
    }
    else
    {
    print "FALSE\n\n";
    }
    
    
    
    $ perl temp1.pl
    [b]TRUE[/b]
    
    $ 
     
  19. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    :)

    A-Z and a-z work too.
     
  20. Joe_Cool

    Joe_Cool Never trust a woman or a government. Moderator

    Joined:
    Jun 30, 2003
    Messages:
    299,246
    Likes Received:
    537
    You might have misread my post. [1-31] failed on "5" but matched on "3". But yeah, I know about ranges.
     
  21. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
    Well fuck me. How do you get it to do 1-31?
     
  22. Peyomp

    Peyomp New Member

    Joined:
    Jan 11, 2002
    Messages:
    14,017
    Likes Received:
    0
  23. GunboatDiplomat

    GunboatDiplomat New Member

    Joined:
    Jun 9, 2006
    Messages:
    214
    Likes Received:
    0
    Not to start a flame war or anything but, as far as I can tell, Ruby is better than Perl in every way...
     
  24. Joe_Cool

    Joe_Cool Never trust a woman or a government. Moderator

    Joined:
    Jun 30, 2003
    Messages:
    299,246
    Likes Received:
    537
    I used (0?[1-9]|[12][0-9]|3[01])

    Not nearly as pretty. :o
     
  25. purebad

    purebad I don't need your approval, right?

    Joined:
    Aug 25, 2006
    Messages:
    4,376
    Likes Received:
    0
    Location:
    Smyrna, GA
    to answer the question up a ways, this is a simple program that takes input from a form, a date, a track, and a race number, and looks up the race info from a file, im just using the perl to do at the input checking/formatting before giving it to a java program. so Im just checking that the date is reasonable.

    so ive been playing around with it this morning, and it still isnt quite right:

    if($date =~ /(1[012]|[1-9])\/([1-9]|[12][1-9]|3[01])\/200[67]/){
    print "$date matched ok<br>";
    }else{
    print "Correct date format:<br>month/day/year<br>AND<br>The day must be 1-31<br>";
    print "The month must be 1-12<br>The year must be 2006 or 2007<br>";
    }

    I just took out the 0x cases, but it will match any month up to 99, after 100 it catches it. the days and years work fine. any ideas?
     
    Last edited: Jan 30, 2007

Share This Page