in reply to negative look-ahead is ignored

Look-aheads and look-behinds are IMO advanced constructions we don't need most of the time for simple problems. They demand more thought and many times are not what we wanted at the end. For example, from your description ("I expected it not to match because of the '-' at the end.") and your two solutions, I would suggest the use of simple /\d{4}-\d{1-3}([^-\d]|$)/, where [^-\d] prevents the pattern to match after 1, 2 or 3 digits and encountering yet another digit or dash, and $ in the alternation makes it succeed at the end of the line.

#!/usr/bin/perl -w use strict ; use warnings; for my $d qw(2005-12 2005-100 2005-1- 2005-12- 2005-123- 2005-1000) { printf "%-10s: ", $d; if ( $d =~ /\d{4}-\d{1,3}([^-\d]|$)/ ) { print "yep\n" ; } else { print "nope\n"; } }
outputs
2005-12 : yep 2005-100 : yep 2005-1- : nope 2005-12- : nope 2005-123- : nope 2005-1000 : nope

Replies are listed 'Best First'.
Re^2: negative look-ahead is ignored
by ikegami (Patriarch) on Feb 19, 2007 at 15:55 UTC

    It's actually possible to avoid matching the extra character by using (?>...).

    for my $d qw(2005-12 2005-100 2005-1- 2005-12- 2005-123- 2005-1000) { printf "%-10s: ", $d; if ( $d =~ /(?>\d{4}-\d{1,3})(?!-)/ ) { print "yep\n" ; } else { print "nope\n"; } }
    2005-12 : yep 2005-100 : yep 2005-1- : nope 2005-12- : nope 2005-123- : nope 2005-1000 : yep

    Use (?![-\d]) if you don't want the last to match.