r@ph said:
It seems delimiters can cause trouble sometimes.
No doubt. Most things can
Look at this :
<script type="text/javascript">
function isDigit(s) {
var DECIMAL = '\\.';
var exp = '/(^[+]?0(' + DECIMAL
+'0+)?$)|(^([-+]?[1-9][0-9]*)$)|(^([-+]?((0?|[1-9][0-9]*)' + DECIMAL
+'(0*[1-9][0-9]*)))$)|(^[-+]?[1-9]+[0-9]*' + DECIMAL +'0+$)/';
ICK. Now I have looked. I need to go wash my eyes. With soap.
Ahem, anyway ...
The "/" at the start and end of "exp" is pretty certainly wrong.
A javascript regexp *literal* is delimited by slashes, e.g.,
/foo|bar/. The corresponding constructor call would be RegExp("foo|bar"),
where the regexp is in a string literal, delimited by the string quotes,
and therefore doesn't need any other delimination ... deliminion ...
something.
The "/"'s above merely cause the first and last alternative of the
regexp to fail because they expect a slash before the start of the
string, or after the end.
return RegExp(exp).test(s);
};
document.write(isDigit('123.45') ? '1' : '0');
document.write(isDigit('123') ? '1' : '0');
document.write(isDigit('123.00') ? '1' : '0');
</script>
With / delimiters, third test fails.
With | delimiters, it's ok.
Where did you put the '|' "delimiters"? In the same palce as the '/'?
Then the first and last alternative would start to work, and you would
also have added two ways of matching the empty substring, meaning that
*all* strings would match. Try isDigit("Arglebargle").
Same behavior with firefox,ie7,safari.
Then it's probably intended behavior.
Can someone explain this ?
Yep, it's what you asked for
Stick to regexp literals if possible, they are easier to read,, and
you don't have to escape your backslashes.
var exp = '/(^[+]?0(' + DECIMAL
+'0+)?$)|(^([-+]?[1-9][0-9]*)$)|(^([-+]?((0?|[1-9][0-9]*)' + DECIMAL
+'(0*[1-9][0-9]*)))$)|(^[-+]?[1-9]+[0-9]*' + DECIMAL +'0+$)/';
If I read the regexp correctly, it should match any of:
- An optional plus and a single zero, optionally followed by a decimal
point and one or more zeros.
- An optional sign and a non-zero digit followed by any number of digits.
- An optional sign and either zero or (a non-zero digit followed by any
number of digits), followed by a decimal point and a sequence of digits
containing at least one non-zero digit.
- An optional sign and a non-zero digit followed by any number of digits,
followed by a decimal point and a nonzero number of zeros.
I.e., an optional sign, either a single zero multiple digits not startine
with a zero, and optionally a decimal point and more than one digit -
except you don't allow minus zero.
It might be easier to use two checks:
/^[-+]?(?:0|[1-9]\d+)(?:\.\d+)?$/
AND NOT
/^-0(?:\.0+)$/
If that's not possible, I think the above can also be made a little
shorter (and avoid the DECIMAL constant, unless you do it for
readablilty):
/^(?:\+?0(?:\.0+)?|[-+]?(?:0\.0*[1-9]\d*|[1-9]\d*(?:\.\d+)?))$/
Best of luck.
/L 'likes regexps'