Update: Pleeaase don't vote++ for this! Having looked at Enlils and Abigails solutions, I realise that this is so over-specified and complicated that it is effectively garbage!

The only saving grace is that I didn't post my first attempt. That was really complicated!

I think this does the trick, though a few more testcases wouldn't go amiss.

(Quickly) updated to correct my misreading of the spec. Date::Manip allows mixed negatives and positives in it's deltas, and I assumed this did too!

#! perl -slw use strict; my $re_dur_years = qr[ (?<= P ) \d+ Y ]x; my $re_dur_months = qr[ (?<= [PY] ) \d+ M ]x; my $re_dur_days = qr[ (?<= [PYM] ) \d+ D ]x; my $re_dur_hours = qr[ (?<= [T] ) \d+ H ]x; my $re_dur_minutes = qr[ (?<= [TH] ) \d+ M ]x; my $re_dur_seconds = qr[ (?<= [THM] ) \d+ (?: \. \d+ )? S ]x; my $re_dur = qr[^ -? P (?= T? -? \d+ ) (?: $re_dur_years? | $re_dur_months? | $re_dur_days? (?: T (?: | $re_dur_hours | $re_dur_minutes | $re_dur_seconds ){1,3} )? ){1,6} $]x; while( <DATA> ) { chomp; print and next if m[^\s*$]; printf "%s %s\n", $_, $_=~ $re_dur ? 'matched' : 'didn\'t match'; } __DATA__ P P1Y P1Y1M P1Y1M1D P1Y1M1DT1H P1Y1M1DT1H1M P1Y1M1DT1H1M1S P1Y1M1DT1H1M1.1S P1M1DT1H1M1.1S P1DT1H1M1.1S PT1H1M1.1S PT1M1.1S PT1.1S PT0.1S P- P-1Y P-1Y-1M P-1Y-1M-1D P-1Y-1M-1DT-1H P-1Y-1M-1DT-1H-1M P-1Y-1M-1DT-1H-1M-1S P-1Y-1M-1DT-1H-1M-1.1S P-1M-1DT-1H-1M-1.1S P-1DT-1H-1M-1.1S PT-1H-1M-1.1S PT-1M-1.1S PT-1.1S PT-0.1S P1H P1M1Y P1D1M P1DT1M PT1Y PT1M PT1D PT1S1M PT1M1H -P1Y P3Y3M3DT3H3M3S P3M3Y3DT3H3M3S P334Y3DT3H3M3S PT2H 5T PT P5M6DT P5M6DT9 P600T6S

Results

P:\test>297188 P didn't match P1Y matched P1Y1M matched P1Y1M1D matched P1Y1M1DT1H matched P1Y1M1DT1H1M matched P1Y1M1DT1H1M1S matched P1Y1M1DT1H1M1.1S matched P1M1DT1H1M1.1S matched P1DT1H1M1.1S matched PT1H1M1.1S matched PT1M1.1S matched PT1.1S matched PT0.1S matched -P didn't match -P1Y matched -P1Y1M matched -P1Y1M1D matched -P1Y1M1DT1H matched -P1Y1M1DT1H1M matched -P1Y1M1DT1H1M1S matched -P1Y1M1DT1H1M1.1S matched -P1M1DT1H1M1.1S matched -P1DT1H1M1.1S matched -PT1H1M1.1S matched -PT1M1.1S matched -PT1.1S matched -PT0.1S matched P1H didn't match P1M1Y didn't match P1D1M didn't match P1DT1M matched PT1Y didn't match PT1M matched PT1D didn't match PT1S1M didn't match PT1M1H didn't match -P1Y matched P3Y3M3DT3H3M3S matched P3M3Y3DT3H3M3S didn't match P334Y3DT3H3M3S matched PT2H matched 5T didn't match PT didn't match P5M6DT matched P5M6DT9 didn't match P600T6S didn't match

Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail

Edited by castaway: closed bold and em tags on update line.

In reply to Re: duration regex by BrowserUk
in thread duration regex by Plankton

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.