Validate Dollar Amount with PHP

3 comments

It can be hard when conducting interviews for a web developer position to really know a candidates skill level.  Recently a company presented me with the following problem, which I thought stood head and shoulders above the usual multiple choice quizzes and simple logic problems I’ve been presented with.

In the language of your choice, write a function that accepts a string. The string is a dollar amount, which may start with a dollar sign, and may have commas in it. Output should be a number, or false if there are illegal characters in the string.

My first instinct was to look for a PHP built in that would do the above, but surprisingly enough, there was none!  So on to my solutions.

While not directly stated in the problem, I assumed that any commas contained in the string must be in a valid position.  (i.e.  $5,0,0,0.00 is no good).  Also, rather than just returning ‘a number’ as the problem states, I return the entire string unaltered if it validates. The first solution is just a regular expression which would work in a preg_match(). The second is more straight forward PHP.

Regular Expression

@^\$?((?:\d{1,3},?)(?:\d{3},?)*(?:\.\d{2})?)$@


PHP Code

function validateDollarAmount($string) {
	if (preg_match('@^\$?([0-9,.]+)$@', $string)) {
		// satisfies basic monetary requirements.  check decimal
		if (strpos($string, ".") !== false) {
			$bits = explode(".", $string, 2);
 
			// decimal must be two numeric digits and be at the end of the string
			$pos = strlen($string) - strpos($string, ".");
 
			if (strlen($bits[1]) != 2 || !preg_match('@[0-9]{2}@', $bits[1]) || $pos != 3) {
				return false;
			}
		}
 
		// check the comma placement - must always have three numbers after it to be sane
		if (strpos($string, ",") !== false) {
			// we only want to deal with the left side of the decimal if there is one
			if (strpos($string, ".") !== false) {
				// only check for commas before decimal
				$bits = explode(".", $string);
				$test = $bits[0];
			} else {
				$test = $string;
			}
 
			$offset = 0;
 
			// loop the string, checking the position of the commas
			while ($offset < strlen($test)) {
				if ($pos = strpos($test, ",", $offset)) {
					// we want the position from the right
					$reverse = strlen($test) - $pos;
 
					// comma must fall in a position divisible by four to be valid
					if ($reverse % 4 !== 0) {
						return false;
					}
 
					$offset = $pos + 1;
				} else {
					break;
				}
			}
		}
 
		return $string;
	}
 
	return false;
}

Even the PHP solution relies on several smaller regular expressions… can you do it without using any at all?

What I really liked about this problem was that at first it seems almost too easy, until you get into the issues of comma placement and things like that. It was actually very tricky and can be a good problem to highlight someones thought process.

July 14th, 2009 at 12:06 pm  

Posted in PHP

3 Responses to 'Validate Dollar Amount with PHP'

Subscribe to comments with RSS or TrackBack to 'Validate Dollar Amount with PHP'.

  1. i found a bug in this code. I entered an amount of 1333,200.00 and it validated. This is not valid, there needs to be a coma after the 1.

    Jason

    11 Sep 09 at 2:25 pm

  2. You’re right Jason. I’ll try to fix that up! I guess I got sloppy when putting together my test cases.

    fdask

    11 Sep 09 at 6:10 pm

  3. I may be dense, but I don’t understand why the preg_match or $pos are necessary on Line 10. I would have thought the following would have been sufficient:

    [php]if (strlen($bits[1]) != 2)[/php]

    Could you shed some light on why the other checks on that line were necessary? (Actually, they all seem to do the same thing – why all three instead of just one of them?)

    Matthew

    2 Feb 10 at 5:27 pm

Leave a Reply