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

I have written the following code to test whether string $s contains between 6 and 20 characters. Furthermore, each character must be either a letter or a number; no fancy characters, including underscores, are allowed.

if( ($s =~ /\w{6,20}/) && ($s !~ /\_/)) {print "success!";} else {print "invalid string";}
And after writing this code I just answered my own question. Sorry guys, no response needed (unless you know of a shorter version of this code).

Replies are listed 'Best First'.
Re: how should i test whether a string contains between 6 and 20 letters and numbers
by GrandFather (Saint) on Jan 30, 2006 at 00:02 UTC
    use strict; use warnings; while (<DATA>) { chomp; if (/^[a-zA-Z0-9]{6,20}$/) { print "Success: >$_<\n"; } else { print "Invalid string: >$_<\n"; } } __DATA__ Success Invalid string!

    Prints:

    Success: >Success< Invalid string: >Invalid string!<

    Update: provide complete sample


    DWIM is Perl's answer to Gödel

      Your solution allows for a trailing newline. Try it with this string:

      $_ = "abcdefghijklm\n\n";

      You can fix that up with the \z anchor :)

      --
      brian d foy <brian@stonehenge.com>
      Subscribe to The Perl Review

        My sample code (the solution is actually the regex /^[a-zA-Z0-9]{6,20}$/) removes trailing line seperators (however they may currently be defined). A blank line will comprise two consecutive line seperators and will result in an invalid string being detected - which is consistent with OP's criteria (and original code).

        Note that at least part of the rationale for posting a "complete sample" is to show others with a technique for providing stand alone code to demonstrate a problem or solution. The line handling code is incedental to the OP's question, but is an important part of a technique for providing test data.

        Hmm, ok I'll go get that coffee now :)


        DWIM is Perl's answer to Gödel
Re: how should i test whether a string contains between 6 and 20 letters and numbers
by brian_d_foy (Abbot) on Jan 30, 2006 at 00:13 UTC

    Your solution tests that there is a run of 6 to 20 word characters (and word characters include the underscore). That doesn't say anything about the total string length or what else is in the string.

    You'll want something like this untested code:

    my $length = length $string; if( $length >= 6 and $length <=20 and $string !~ /[^a-z0-9]/i ) { ... }
    --
    brian d foy <brian@stonehenge.com>
    Subscribe to The Perl Review
Re: how should i test whether a string contains between 6 and 20 letters and numbers
by helphand (Pilgrim) on Jan 30, 2006 at 00:17 UTC
    use strict; use warnings; my $str = $ARGV[0]; if ($str =~ /^[a-zA-Z0-9]{6,20}$/) { print "success!\n"; } else { print "failure\n"; }

    A bit shorter.

    Scott

Re: how should i test whether a string contains between 6 and 20 letters and numbers
by Aristotle (Chancellor) on Jan 30, 2006 at 17:11 UTC

    It’s not shortness that counts, it’s matching closely what you intend the code to mean. Your original code is not very good because you don’t mean “check if it’s between 6 and 20 letters, numbers and underscores, but make sure it has no underscores.” You mean “check that it’s between 6 and 20 letters and numbers,” so that’s what the code should do:

    print( ( $s =~ m{ \A [[:alnum:]]{6,20} \z }x ) ? "success" : "invalid +string" );

    Makeshifts last the longest.

Re: how should i test whether a string contains between 6 and 20 letters and numbers
by Rhandom (Curate) on Jan 30, 2006 at 15:21 UTC
    Well - this lets UNICODE letters in the door - but it is letters or numbers...
    if ($s=~ /^ [^\W_]{6,20} $/x) { print "success!"; }
    my @a=qw(random brilliant braindead); print $a[rand(@a)];