Page 1 of 1

Is string a float (alternative to regex)

Posted: Sun May 20, 2007 3:28 am
by Stryks
I've been playing with a way to find out if a string is a valid number, allowing that a valid value might be something like
1,234.56
None of the standard functions (is_numeric / is_float / ctype_digit) seem to give me the right results without allowing hex values while still allowing comma separators.

I could have gone with regular expressions, but I was hoping I could achieve this task without going that way. It's also worth noting that I'm not interested if it is actually valid, just that it doesn't contain any other characters.

Code: Select all

<?php
$test = array("123", "123.45", "one.34", "123.45.67", "one", 12.52, "", "1,234.50", "1,234,567.89");

foreach ($test as $test_val) {
	echo "Is $test_val an integer? ";
	if(isNumber($test_val)) echo " Yes"; else echo "No";
	echo "<br><br>";
}

function isNumber($value) {
	@list($integer, $remainder) = explode(".", $value);
	$int_segment = explode(",", $integer);

	foreach($int_segment as $segment) if(!ctype_digit($segment)) return false;
	if(!is_null($remainder) && !ctype_digit($remainder)) return false;

//	echo "( evaluates as " . implode(",", $int_segment) . ".$remainder )";

	return true;
}

?>
This should give
Is 123 an integer? ( evaluates as 123. ) Yes

Is 123.45 an integer? ( evaluates as 123.45 ) Yes

Is one.34 an integer? No

Is 123.45.67 an integer? ( evaluates as 123.45 ) Yes

Is one an integer? No

Is 12.52 an integer? ( evaluates as 12.52 ) Yes

Is an integer? No

Is 1,234.50 an integer? ( evaluates as 1,234.50 ) Yes

Is 1,234,567.89 an integer? ( evaluates as 1,234,567.89 ) Yes
Any thoughts on this? Potential issues or problems? Should I just use regular expressions?

Thanks for reading.

Re: Is string a float (alternative to regex)

Posted: Sun May 20, 2007 6:08 am
by stereofrog
Stryks wrote:Should I just use regular expressions?
Yes. One line of code is always better than 20.

Posted: Sun May 20, 2007 7:17 am
by feyd
Plus, locales will change what "," and "." mean.

Posted: Sun May 20, 2007 7:21 am
by Stryks
Thanks for the reply ...

My reluctance to go with regex for this is primarily from people always mentioning that if regex isnt specifically required, then dont use it. Usually they include references to avoiding the overhead regex requires, presumably from loading the handling code ... I dont know.

Do regex calls take a performance hit, and what, realistically, is the point when you consider the hit acceptable?

Also, if there is a performance hit, what about where multiple calls are made? Does this overhead take place only for the first call, or for each call?

I'm still learning regex, so I'd really love to hear some straight answers on what is proving to be a very curly process.

Cheers.

Posted: Sun May 20, 2007 8:51 am
by Stryks
Ok ... I dont know how I'm doing ... this seems to work but is somehow less attractive than alot of regex I see around.

So .. as far as regex goes .... I came up with :

Code: Select all

preg_match('/\\A(?:(?:[\\d]*[,])?)*[\\d]{0,3}[.]?[\\d]*\\z/', $value)
How did I do here?

Anyone have anything more compact? Also, I'm thinking it should be a smallish deal to make sure values between ,'s and the . is 3 characters long. Maybe I shouldn't be concerned about this.

When storing the value, I will format the number to lose the commas and restrict decimal places to 2, but I want to make sure it's a valid number first, so that I can be sure it will format without loss.

Thanks for any assistance

Posted: Sun May 20, 2007 8:53 am
by Stryks
Oh ... just to clarify ... I say it should be a smallish deal to check the number of digits between markers, but I have no idea how to do it or where to start.

Assistance would help out a lot.

Cheers