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

I am trying to debug someone else's code and I am stuck with a regex issue. I have a textarea and I am running the regex to limit it to 1100 words. The regex she wrote seems to pick up when the 1100 limit is reached, however does not stop the user from entering more than 1100 characters. First can someone tell me exactly what I have here:
validation-regex="(?s)^.{0,1100}$
I have a pretty good idea of what this does, but I am gray on how all the symbols are working together. Second what is the best way to go about putting in a stop on the textarea to not allow the user to enter more than 1100 chars? Thanks

Replies are listed 'Best First'.
(Ovid) Re: Regex help
by Ovid (Cardinal) on Jun 15, 2001 at 20:40 UTC

    Assuming that you have accidentally left off a final quote, I am assuming that someone tried to get cute with a regex and dropped the ball. Here's what I think was meant:

    $validation-regex="^(?s:.{0,1100})$";

    The following would be an equivalent regex:

    $string =~ /^.{0,1100}$/s;

    The (?s:) construct turns on the appropriate modifer for the whatever in included in the parens. In this case, it appears that the author of the regex is trying to match 0 to 1100 characters (not words) and that the /s modifier was tossed in to make the dot match the newline.

    Reading through perlre, you'll see that you can use the (?misx-misx:) construct to turn switches off an on for a particular section of the regex. For example, what if you're trying to match MacDonald? Those first four letters could be virtually any case, but we don't want to make the entire regex match case-insensitive as that would be inefficient. Here's on way to match it:

    $last_name =~ /(?i:macd)onald/;
    That makes the 'macd' part a case-insensitive match, but the rest is still required to have an exact match.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: Regex help
by arturo (Vicar) on Jun 15, 2001 at 20:34 UTC

    There's a maxlength attribute in HTML for text input fields, but not for textarea. If you want to limit a string to 1100 chars max after you've got it into a variable, then

    $string = substr($string,0, 1100) if length $string > 1100;

    oughta do. Moral of the story: not everything one does with a string ought to be implemented in regexes.

    perl -e 'print "How sweet does a rose smell? "; chomp ($n = <STDIN>); +$rose = "smells sweet to degree $n"; *other_name = *rose; print "$oth +er_name\n"'
Re: Regex help
by wardk (Deacon) on Jun 15, 2001 at 20:43 UTC

    Our forms (here at work) utilize javascript for limiting text. I don't think there is a perl way to do this.

    despite my reservations, I am gonna post non-perl code (at least it's generated by perl).

    this is a js routine that will handle it...

    function checkTextAreaLen( fName, theField, maxLen ) { if ( theField.value.length > maxLen ) return msgErrorMid( fName, theField, maxLen, "Please enter less th +an ", " characters into the \"", "\" field. \nCurrently there are " + + theField.value.length + " characters in the field." ); return true; } ## and here is the onChange that invokes it from a textarea, limiting + to 1500 chars onChange="checkTextAreaLen(gsJobdesc,this,1500)

    now I have to find a way to purge away the sin I have committed...suggestions are welcome

      you really ought to doublecheck the length on the server too if that's in a form that gets submitted. a user may have javascript turned off, or, if your systems would break on too much input, a (cr|h)acker might manually send you longer input as a DOS.

      point is, you should never rely on client-side code to validate forms.

      anders pearson // digital samurai
      personal      // http://www.columbia.edu/~anders/
      weblog       // http://thraxil.dhs.org/
      
        point is, you should never rely on client-side code to validate forms.

        I wholehearetdly agree, our use of javascript in this case is to just to prevent a post if the length is out of bounds with a textarea. when the form gets posted, the real validations take place (a fun place where MS word formatting characters are sanitized and fed to oracle) via perl. We also handle forcing/restricting alpha/numerics, etc I inherited the system (on contract), but given the user requirements, I can't see how it could have been done any other way. (the requirements were specifically for popup warnings, which while annoying save posts to the busy server)

        btw, this being an internal business app, we have only have to code to one browser, netscape 4.x and require javascript. a very controlled environment. there are plenty of other reasons on top of what we're discussing that would disqualify it for general net use. :-)

Re: Regex help
by petdance (Parson) on Jun 15, 2001 at 20:35 UTC
    You can't, from the server side, control what the user enters into the TEXTAREA field.

    If all you want to do is trim the string to be 1100 characters at most, just do this:

    use constant MAX_CHARS => 1100; if ( length($str) > MAX_CHARS ) { $str = substr( $str, 0, MAX_CHARS ); }
    update: As a later reply points out, the length test is not necessary. If you don't want to do the test, at least point out WHY it is that you're calling substr.
    # Limit the string's length $str = substr( $str, 0, MAX_CHARS );

    xoxo,
    Andy

    %_=split/;/,".;;n;u;e;ot;t;her;c; ".   #   Andy Lester
    'Perl ;@; a;a;j;m;er;y;t;p;n;d;s;o;'.  #   http://petdance.com
    "hack";print map delete$_{$_},split//,q<   andy@petdance.com   >
    
      The length tests on this and most of the other answers in this thread are unnecessary. As the documentation for substr states:
      If OFFSET and LENGTH specify a substring that is partly outside the string, only the part within the string is returned.
         MeowChow                                   
                     s aamecha.s a..a\u$&owag.print
Re: Regex help
by damian1301 (Curate) on Jun 15, 2001 at 20:35 UTC
    Yeah, use substr...:
    if(length $input >1100){substr($_,0,1100);} # delete everything after 1100 chars


    UPDATE: Too bad everyone beat me to it!

    Tiptoeing up to a Perl hacker.
    Dave AKA damian

Re: Regex help
by cLive ;-) (Prior) on Jun 15, 2001 at 21:02 UTC
    Since nobody seems to have answered :):
    (?s) - see [Ovid]'s answer ^ - beginning of string .{0,1100} - between 0 and 1100 characters $ end of string

    And other points below:

    • yes you can use javascript, but cannot *rely* on it, so always add server side check
    • $string = substr($string,0, 1100) is quick solution
    • or trim and add ... if you want to show it was longer, using something like <CODE>$string =~ s/^(.{0,1096}) .*$/$1.../ if length($string)>=1100);

    TIMTOWTFIU

    cLive ;-)

Re: Regex help
by Zaxo (Archbishop) on Jun 15, 2001 at 20:42 UTC

    Why not test with do{use bytes; length($string);}? Or substr if you want to be forgiving and trim oversized data?

    After Compline,
    Zaxo

Re: Regex help
by dimmesdale (Friar) on Jun 15, 2001 at 21:41 UTC
    As its been said, your regex matches 1,100 CHARACTERS, not words(also, I believe the $ should be escaped, since its in a double-quoted string). If you wish to limit it to 1,100 words you have a problem--defining what constitutes a word. Once done, you have several options--and depending on what constitutes a word for your purposes, a regex isn't always the fastest way. Post again (including your def. of a word) if you want to limit it to 1,100 words, and you can get some help with that, otherwise solutions have already been offered as per 1,100 characters.