Greatly appreciate your commenting.
What you do here is first to substitute any whitespace characters by blanks, then all blanks by nothing and then you look for blank at the beginning and the end of your data. As your RegEx to validate input is $data =~ /^(-\@\w. +)$/, I would guess that you might have wanted to leave the second RegEx out.
The second RegEx contains two spaces (not one), so what it does is remove extra spaces but one to nothing. | [reply] |
The second RegEx contains two spaces (not one), so what it does is remove extra spaces but one to nothing.
Huh? If I understand your statement, then you might not understand the process...
$data =~ s/\s+/ /g;
# Remove extra spaces to nothing
$data =~ s/ +//g;
Regardless of what sort of whitespace is contained in $data, your first regex eliminates all cases where two or more whitespace characters are adjacent -- it changes every string of one or more whitespace to a single space -- which means there will be nothing left for your second regex to apply to, so the second one is not needed.
(And if you were to apply the second regex to a string that happened to contain two or more consecutive spaces -- i.e. where the first regex had not been applied -- it would delete all the spaces in that sequence, not leaving any behind.)
As for the rest, I second the earlier suggestions to look at established modules for this sort of thing, especially if you expect there will be an increasing need for it.
Also, just as a matter of style, it's often nicer to have the shorter, simpler, and/or more primary conditions fully handled first, and deeper, more complicated ones later. In general, this allows for simpler code, with less nesting of "if ... else ..." conditions; eg:
$length = length( $data );
if ( ! $length ) { # empty string
if ( $obligatory ) {
bail_out( "Obligatory field not filled in" );
} else {
return;
}
}
if ( $data =~ /([^-\@\w. ])/) {
bail_out( "Bad character: $1 -- Only alphanumerics and -@. allowed"
+ );
}
if ( $numeric and $data =~ /[^\d]/ ) {
bail_out( "Non-numeric character(s) in numeric field" );
}
if ( $min and $length < $min ) {
bail_out( "too short" );
}
if ( $max and $length > $max ) {
bail_out( "too long" );
}
return $data;
I haven't tested it, but I think that covers everything you posted. Instead of being a long block of nested logic, it's a set of simple, discrete checks, arranged in such a way that the later ones only need to be checked if the earlier ones pass. Note that the case of $min==$max does not need special treatment, and the checks for acceptable character content and for digits involve seeing if any unacceptable characters are present.
(Is it possible that negative and/or decimal-fraction numbers should be allowed in some numeric fields? If so, that condition should be: $data =~ /[^\d.-]/)
(update: fixed the code slightly, to give a better error message in the character-class check. Did some rewording.) | [reply] [d/l] [select] |
Great thanks, graff!
I appreciate your re-writing the code. It's definitely a lot easier to read and understand than the one I've (btw, does your cover the exact length part i.e if the string has to be exactly a certain length? I'll test that out later when I get home.)
I think I misunderstood the regex part. Thanks for pointing out :)
update
Note that the case of $min==$max does not need special treatment
Missed that out earlier.
| [reply] |