http://www.perlmonks.org?node_id=997825


in reply to Re^2: Quick Regex Question
in thread Quick Regex Question

OK, change the regex to:

/INC\d{7}(?:[^\d]|$)/

which should match only exactly 7 digits. (INC followed by 7 digits followed by either a non-digit or the end of the string.)

Update: Better solutions:

/INC\d{7}(?!\d)/

using a zero-width negative look-ahead assertion; or:

/INC\d{7}(?:(?=\D)|$)/ # Corrected: See post by AnomalousMonk, belo +w.

using a zero-width positive look-ahead assertion together with \D as per GrandFather’s suggestion. See Extended Patterns.

Athanasius <°(((><contra mundum

Replies are listed 'Best First'.
Re^4: Quick Regex Question
by GrandFather (Saint) on Oct 08, 2012 at 23:29 UTC

    You can use \D for "not a digit". In like fashion you can use \W and \S to complement the common word and space matches.

    True laziness is hard work
Re^4: Quick Regex Question
by AnomalousMonk (Archbishop) on Oct 09, 2012 at 12:36 UTC
    ... using a zero-width negative look-ahead assertion; or ... using a z +ero-width positive look-ahead assertion together with \D ...

    Note that  (?!\d) and  (?=\D) are not complementaryequivalent. The  (?!\d) assertion is satisfied by having any non-digit follow it or by nothing, i.e., by the end of the string, nothing being not-a-digit. The  (?=\D) assertion must be followed by a non-digit character. And similarly with the  (?<!\d) and  (?<=\D) look-behinds.

    >perl -wMstrict -le "my $s = 'xyzINC1234567'; ;; print 'negative assertion true' if $s =~ /INC\d{7}(?!\d)/; print 'positive assertion true' if $s =~ /INC\d{7}(?=\D)/; " negative assertion true

    In this behavior,  (?!\d) and, in general,  (?!character-or-character-class) and its negative look-behind cousin are similar to (but not exactly the same as) the  \b assertion, which may be true at the beginning or end of a string.