sign in | join about | help | sitemap
Connecting Tech Pros Worldwide
r@ph's Avatar

Strange RegExp problem


Question posted by: r@ph (Guest) on October 14th, 2008 05:05 PM
Hello,

It seems delimiters can cause trouble sometimes.

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+$)/';
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.

Same behavior with firefox,ie7,safari.

Can someone explain this ?

Thanks.


4 Answers Posted
Martin Honnen's Avatar
Guest - n/a Posts
#2: Re: Strange RegExp problem

r@ph wrote:
Quote:
Originally Posted by
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+$)/';
return RegExp(exp).test(s);


// serve as delimiters for regular expression literals. You don't use
them in strings passed to the RegExp constructor, unless you really want
to match a slash.

--

Martin Honnen
http://JavaScript.FAQTs.com/
r@ph's Avatar
Guest - n/a Posts
#3: Re: Strange RegExp problem

> var exp = '/(^[+]?0(' + DECIMAL
Quote:
Originally Posted by
Quote:
Originally Posted by
>+'0+)?$)|(^([-+]?[1-9][0-9]*)$)|(^([-+]?((0?|[1-9][0-9]*)' + DECIMAL
>+'(0*[1-9][0-9]*)))$)|(^[-+]?[1-9]+[0-9]*' + DECIMAL +'0+$)/';
> return RegExp(exp).test(s);

Quote:
Originally Posted by
// serve as delimiters for regular expression literals. You don't use them
in strings passed to the RegExp constructor, unless you really want to
match a slash.



Hi Martin,
Can you explain this a little more please ?
In my sample, why only the 3rd case fails ?
Thanks a lot.


Lasse Reichstein Nielsen's Avatar
Lasse Reichstein Nielsen October 14th, 2008 06:35 PM
Guest - n/a Posts
#4: Re: Strange RegExp problem

"r@ph" <r-a-p-h-sans-tirets@inrezo.comwrites:
Quote:
Originally Posted by
It seems delimiters can cause trouble sometimes.


No doubt. Most things can :)
Quote:
Originally Posted by
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.
Quote:
Originally Posted by
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").
Quote:
Originally Posted by
Same behavior with firefox,ie7,safari.


Then it's probably intended behavior.
Quote:
Originally Posted by
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.
Quote:
Originally Posted by
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'
--
Lasse Reichstein Holst Nielsen
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
r@ph's Avatar
Guest - n/a Posts
#5: Re: Strange RegExp problem

Hello,

Thanks for this complete answer.
Quote:
Originally Posted by
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.


Understood.
Quote:
Originally Posted by
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").


Exact. I'm confused :S


This code and my problem come from the tablesorter jquery plugin. I warn the
author now.

Thanks again.
Raph


 
Not the answer you were looking for? Post your question . . .
197,027 members ready to help you find a solution.
Join Bytes.com

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 197,027 network members.
Post your question now . . .
It's fast and it's free

Popular Articles

Top Community Contributors