Hagbone has asked for the wisdom of the Perl Monks concerning the following question:

Grettings, oh wise ones... Friar Hagbone is scratching what little hair is left on his sparse pate ....... I'm trying to craft a regex that controls the quantity of bracketed items. For example, the regex below will allow any number of lowercase letters and numbers, providing the entry doesn't begin or end with a space(s)
/^[^ ]+[a-z0-9]+[^ ]+$/
What I'd like to do is also specify the minimum (5) and maximum (12) number of characters allowed ...., and I tried:
/^[^ ]+[a-z0-9]{5,12}[^ ]+$/
But that doesn't appear to do it .... can anyone straighten me out on this one?

Replies are listed 'Best First'.
Re: Regex: Specifying quantity for bracketed items
by tall_man (Parson) on Nov 10, 2004 at 21:21 UTC
    You aren't matching what you think you are. The [^ ]+ greedily matches all the letters and numbers but one, as this example will show:
    $_ = "\@abcde99\@"; if (/^([^ ]+)([a-z0-9]+)([^ ]+)$/) { # prints: *@abcde9*9*@* print "*$1*$2*$3*\n"; }
    A better regex might be this one:
    $_ = "\@abcde99\@"; if (/^([^ ]+?)([a-z0-9]{5,12})([^ a-z0-9]+)$/) { print "*$1*$2*$3*\n"; }
Re: Regex: Specifying quantity for bracketed items
by tachyon (Chancellor) on Nov 10, 2004 at 21:32 UTC

    The reason that your RE does not work as expect is that the [^ ]+ atom will match any number of non space chars, which effectively makes your 5,12 limit useless. You first regex is also (probably) broken as it will match all sorts of non lowercase stuff. Here is what it does:

    while(<DATA>) { chomp; print "Matches like: ($1)($2)($3)\n" if m/^([^ ]+)([a-z0-9]+)([^ ] ++)$/ } __DATA__ >>>>this<<<< $$$$that$$$$

    As suggested you probably want m/^[a-z0-9]+$/ which will only match strings that are lowercase or numbers. Changing the + to {MIN,MAX) limits the number. If you want something special at the begining or end of the string using lookback and lookahead assertions may be relevant. However given that a space is not part of your match class.....

    cheers

    tachyon

Re: Regex: Specifying quantity for bracketed items
by injunjoel (Priest) on Nov 10, 2004 at 21:17 UTC
    Greetings all,
    would something like this work?
    /^[a-z0-9]{5,12}$/i
    The ^ and $ will ensure that the string doesn't start or end with a space.

    -InjunJoel
    "I do not feel obliged to believe that the same God who endowed us with sense, reason and intellect has intended us to forego their use." -Galileo
Re: Regex: Specifying quantity for bracketed items
by ikegami (Patriarch) on Nov 10, 2004 at 21:36 UTC

    Maybe you want something like this:

    / ^(?![ ]) # Doesn't start with a space .*? # Anything [a-z0-9]{5,12} # Has a 5..12 lowercases or digits in a row .* # Anything (?<![ ])$ # Doesn't end with a space /x

    which will match
    a1b2c3
    BVBDa1b2c3
    a1b2c3ZZZ
    !@#a1b2c3$%^
    ! a1b2c3 FF

      Actually, that doesn't limit you to 5..12, that matches anything with at least 5 lowercases or digits in a row. Any more than 12 just get sucked into the .* after it. Which makes it equivalent to
      / ^(?![ ]) # Doesn't start with a space .*? # Anything [a-z0-9]{5} # Has 5 lowercases or digits in a row .* # Anything (possibly more lowercases or digits) (?<![ ])$ # Doesn't end with a space /x

        Right you are! Fixed below.

        / ^(?![ ]) # Doesn't start with a space .*? # Anything (?<![a-z0-9]) # For the {5,12} to be meaningful. [a-z0-9]{5,12} # Has a 5..12 lowercases or digits in a row (?![a-z0-9]) # For the {5,12} to be meaningful. .* # Anything (?<![ ])$ # Doesn't end with a space /x
Re: Regex: Specifying quantity for bracketed items
by Hagbone (Monk) on Nov 11, 2004 at 00:05 UTC
    Ahhh the post (albiet corrected) above appears to be just what I was looking for .... many, many thanks.

    Regex's ..... if brains were muscles, regex's would be a prescribed workout (at least for me;)

    Thanks much to all who replied