开发者

How to check if an entered value is currency

How to check if an entered value is currency. Preferably by regular expression or php funct开发者_Go百科ion.

(values like 1550.50, 1500 or 100.75)


I guess what you really want is a way to tell any number from a number that makes sense as a currency value. So 1.04e-7 probably shouldn't match, and neither should 1.234 or 12.3, even though all are of course numeric.

Finally, you'd have to expect thousands separators like 1,234.56 (which, like the decimal point, might also vary between locales). So, assuming that you only ever want to check currency values using the dot as decimal separator and the comma as an optional thousands separator, try this:

/\b\d{1,3}(?:,?\d{3})*(?:\.\d{2})?\b/

Explanation:

\b      # word boundary assertion
\d{1,3} # 1-3 digits
(?:     # followed by this group...
 ,?     # an optional comma
 \d{3}  # exactly three digits
)*      # ...any number of times
(?:     # followed by this group...
 \.     # a literal dot
 \d{2}  # exactly two digits
)?      # ...zero or one times
\b      # word boundary assertion


I use this:

function isCurrency($number)
{
  return preg_match("/^-?[0-9]+(?:\.[0-9]{1,2})?$/", $number);
}

//usage examples
echo (isCurrency("10.36") ? "TRUE" : "FALSE");
echo (isCurrency(10.3) ? "TRUE" : "FALSE");

Beware of:

  1. this function accepts also negative currency values, if you don't want to accept them remove the -? that you find at the beginning of the preg_match

  2. this function returns TRUE also for values like 13.7 (only one decimal), if you want the decimal to be always two than replace {1,2} with {2} (but prior doing this read point 3 below)

  3. this function returns TRUE also for values like 0000.78 (more than one leading zero), but usually this kind of function is needed to filter value submitted by forms before inserting them into DB fields of type DECIMAL(n.2). When inserting in these kind of fields MySQL accepts both 0000.78 and 13.7 as valid values in query, and auto converts them into 0.78 and 13.70


Based on Tim Pietzcker great answer above, I created:

/* Sample usage:
 * ============
 *  echo '<ol>';
 *  echo '<li>', (isCurrency('10.36') ? "TRUE" : "FALSE"), '</li>'; // 1 - TRUE
 *  echo '<li>', (isCurrency('10.3') ? "TRUE" : "FALSE"), '</li>';  // 2 - TRUE
 *  echo '<li>', (isCurrency('10.') ? "TRUE" : "FALSE"), '</li>';   // 3 - TRUE
 *  echo '<li>', (isCurrency('10') ? "TRUE" : "FALSE"), '</li>';    // 4 - TRUE
 *  echo '<li>', (isCurrency('1,088,888,888,888') ? "TRUE" : "FALSE"), '</li>'; // 5 - TRUE
 *  echo '<li>', (isCurrency('1,088888,888,888') ? "TRUE" : "FALSE"), '</li>';  // 6 - I'm not sure if this should return TRUE or FALSE. For now going with TRUE as we can still interpret the desired value regardless whether the commas are correct.
 *  echo '<li>', (isCurrency('$10') ? "TRUE" : "FALSE"), '</li>';   // 7 - TRUE
 *  echo '<li>', (isCurrency('-10') ? "TRUE" : "FALSE"), '</li>';   // 8 - TRUE
 *  echo '<li>', (isCurrency('$-10') ? "TRUE" : "FALSE"), '</li>';  // 9 - TRUE
 *  echo '<li>', (isCurrency('-$10') ? "TRUE" : "FALSE"), '</li>';  // 10 - TRUE
 *  echo '<li>', (isCurrency('--$10') ? "TRUE" : "FALSE"), '</li>'; // 11 - FALSE
 *  echo '<li>', (isCurrency('-$$10') ? "TRUE" : "FALSE"), '</li>'; // 12 - FALSE
 *  echo '<li>', (isCurrency('10x') ? "TRUE" : "FALSE"), '</li>';   // 13 - FALSE
 *  echo '<li>', (isCurrency('x10') ? "TRUE" : "FALSE"), '</li>';   // 14 - FALSE
 *  echo '</ol>'; */
    function isCurrency (string $currencyToTest): bool
    {
    $regExpPattern = '/^[$-]{0,2}\d{1,3}(?:,?\d{3})*(?:\.\d{0,2})?$/';

/*      $regExpPattern explanation
            /^          # string must begin with
            [$-](0,2)   # optional $ and/or -
            \d{1,3}     # 1-3 digits
            (?:         # followed by this group...
             ,?         # an optional comma
             \d{3}      # exactly three digits
            )*          # ...any number of times
            (?:         # followed by this group...
             \.         # a literal dot
             \d{2}      # exactly two digits
            )?          # ...zero or one times 
            $/          # must end with
*/
        $currencyToTest = trim ($currencyToTest);
        
        return preg_match ($regExpPattern, $currencyToTest);
    }

Added:

  • Ability to prefix with $ and/or -.
  • Added ability for no decimal points as in $4.
  • Value to test must be alone in parm.

Without Tim Pietzcker response, not sure I would have gotten this far.


You can't be sure. The user might be thinking of chickens. You need to check if the user entered a float. Have a look at preg_match: http://jp2.php.net/manual/en/function.preg-match.php

You also need to ask yourself if you want to try to work with what the user entered, or if you want to reject it and only accept an exact format.


I quickly spun up a function for checking if a string or int is a valid price and if not, converting it. The final output is always going to be a string with two digits after the decimal, like 1000.00.

It removes minus/negative signs, commas, spaces, and dollar signs. The only except is when if the string contains any characters like letters that would set is_numeric() to false.

Here is the function:

function convertToValidPrice($price) {
    $price = str_replace(['-', ',', '$', ' '], '', $price);
    if(!is_numeric($price)) {
        $price = null;
    } else {
        if(strpos($price, '.') !== false) {
            $dollarExplode = explode('.', $price);
            $dollar = $dollarExplode[0];
            $cents = $dollarExplode[1];
            if(strlen($cents) === 0) {
                $cents = '00';
            } elseif(strlen($cents) === 1) {
                $cents = $cents.'0';
            } elseif(strlen($cents) > 2) {
                $cents = substr($cents, 0, 2);
            }
            $price = $dollar.'.'.$cents;
        } else {
            $cents = '00';
            $price = $price.'.'.$cents;
        }
    }

    return $price;
}

And here is to test it:

var_dump(convertToValidPrice('100'));          // 100.00
var_dump(convertToValidPrice('-100'));         // 100.00
var_dump(convertToValidPrice(100));            // 100.00
var_dump(convertToValidPrice('$100'));         // 100.00
var_dump(convertToValidPrice('100.98'));       // 100.98
var_dump(convertToValidPrice('100.9'));        // 100.90
var_dump(convertToValidPrice('100.'));         // 100.00
var_dump(convertToValidPrice('1,00.98'));      // 100.98
var_dump(convertToValidPrice('1,000.98'));     // 1000.98
var_dump(convertToValidPrice('100.98829382')); // 100.98
var_dump(convertToValidPrice('abc'));          // null
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜