Wrox Programmer Forums
Go Back   Wrox Programmer Forums > PHP/MySQL > Beginning PHP
|
Beginning PHP Beginning-level PHP discussions. More advanced coders should post to the Pro PHP forum.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the Beginning PHP section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old August 18th, 2003, 09:49 PM
Authorized User
 
Join Date: Jul 2003
Posts: 20
Thanks: 0
Thanked 0 Times in 0 Posts
Default Regular expression for currency

Hello,

I read up on regular expressions and after a lot of trial and error I came up with the following function to check to see if a variable contains valid "currency" data.

function isDigits($price) {
return !preg_match("/[^0-9\.]/",$price);
}

It works - sort of. I want to make sure that, at most, only one decimal point is allowed but I'm not sure how to do this. I've tried numerous combinations but, to be honest, I'm just guessing now! Any pointers would be appreciated. Thanks.

 
Old August 18th, 2003, 10:55 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 836
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Quote:
quote:Originally posted by jakeone
 Hello,

I read up on regular expressions and after a lot of trial and error I came up with the following function to check to see if a variable contains valid "currency" data.

function isDigits($price) {
return !preg_match("/[^0-9\.]/",$price);
}

It works - sort of. I want to make sure that, at most, only one decimal point is allowed but I'm not sure how to do this. I've tried numerous combinations but, to be honest, I'm just guessing now! Any pointers would be appreciated. Thanks.
I don't know how your regular expression works, to be honest! Your regular expression looks like it searches for a single character, which can't be a digit or a decimal point. That's not really what you intended, I think.

A better approach might be to try and match the entire currency number. Before we can do that, we need to define what a valid currency is.

Let's say a currency can have an optional leading dollar sign and any amount of leading whitespace (before or after the $), followed by at least one digit, followed by an optional decimal sign and two additional digits.

Valid currencies, therefore, include:
  4
$ 523985.59
$56
    529.30

Invalid currencies include:
$$42
$ 52.0
235.003

The regular expression needs to begin with a leading optional dollar sign surrounded by optional whitespace:

$patt = '/^\s*[$]?\s*


Followed by some number of digits
$patt = '/^\s*[$]?\s*\d+

Followed by an optional decimal point and two cent digits
$patt = '/^\s*[$]?\s*\d+(\.\d{2})?

Followed by some additional optional whitespace, I guess:
$patt = '/^\s*[$]?\s*\d+(\.\d{2})?\s*$/';


Keep in mind I haven't tried this out, so play with it.

You could also mess around with commas in the price. Commas must be preceeded by 1, 2, or 3 digits, and can only contain three digits after it before the next punctuation (comma or decimal point).

$patt = '/^\s*[$]?\s*\d{1,3}(\,\d{1,3})+(\.\d{2})?\s*$/';

The main part of this pattern is this:

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

This means 1-3 digits
  \d{1,3}

followed by zero or more comma-and-three-digits blocks
  (\,\d{3})*

followed by an optional decimal point and two cent digits
  (\.\d{2})?


Extending this example even further, you can combine both approaches -- a currency can either be all digits followed by the optional decimal and cents part, or it can be properly formatted with commas, but it can't be both -- that is, you can't have 2345,234.32

To do this, you need to use the OR operator: |.

In pseudocode:

$patt = '/optional whitespace and dollar sign'
      . 'either all digits (A) or comma-formatted digits (B)'
      . 'an optional decimal and cents part'
      . 'optional trailing whitespace/';


In PHP:
Code:
$patt = '/^\s*[$]?\s*((\d+)|(\d{1,3}(\,\d{3})+))(\.\d{2})?\s*$/';
                     |\---/|\-----------------/|
                     |  A  OR        B         |
                     \-------------------------/
                        Outer grouping parens

I've tested this minimally, and it seems to work okay... play with it and let me know how it goes.


Take care,

Nik
http://www.bigaction.org/
 
Old August 18th, 2003, 10:57 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 836
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Just a follow up: Here's the test script I wrote for the previous reply in it's entirety:

Code:
<?php

$currencies = array("   $   42.52   ",
                    "$   4232395",
                    "4112412",
                    "1296.932",
                    "239583.52",
                    "$  214127 5.23",
                    "$  3223.23",
                    " 234235.2",
                    "$2342.2",
                    "234h",
                    "$123,234.53",
                    "$123,235",
                    "1223,123",
                    "$  123,234,325.23",
                    "$  2354,234.32",
                    "$  123,234,345.455",
                    "$592.235,353");

$simple = '/^\s*[$]?\s*\d+(\.\d{2})?\s*$/';
$commas = '/^\s*[$]?\s*\d{1,3}(\,\d{3})*(\.\d{2})?\s*$/';
$both   = '/^\s*[$]?\s*((\d+)|(\d{1,3}(\,\d{3})+))(\.\d{2})?\s*$/';

echo <<<EOH
<table border="1" cellspacing="0">
  <tr>
     <th>currency</th>
     <th>simple</th>
     <th>comma</th>
     <th>both</th>
   </tr>

EOH;

foreach($currencies as $curr)
{
    $m_simple = preg_match($simple, $curr, $matches)? "X" : "&nbsp;";
    $m_commas = preg_match($commas, $curr, $matches)? "X" : "&nbsp;";
    $m_both   = preg_match($both,   $curr, $matches)? "X" : "&nbsp;";

    echo "  <tr>\n";
    echo "    <td>$curr</td>\n";
    echo "    <td>{$m_simple}</td>\n";
    echo "    <td>{$m_commas}</td>\n";
    echo "    <td>{$m_both}</td>\n";
    echo "  </tr>\n";
}
echo "</table>\n";
?>

Take care,

Nik
http://www.bigaction.org/
 
Old August 19th, 2003, 04:10 AM
Authorized User
 
Join Date: Jul 2003
Posts: 20
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Nikolai,

Thanks for the comprehensive reply. I will work on it later today!

Jake






Similar Threads
Thread Thread Starter Forum Replies Last Post
Regular Expression Help Please rstelma ASP.NET 1.0 and 1.1 Professional 0 January 2nd, 2008 07:01 PM
What will be the regular expression for following? [email protected] ASP.NET 1.0 and 1.1 Basics 2 December 26th, 2006 06:49 AM
regular expression vohra_vikas2004 ADO.NET 3 November 18th, 2004 09:59 PM
Regular Expression Help Greg Griffiths Javascript How-To 4 November 12th, 2004 05:33 AM
Regular Expression DARSIN General .NET 2 November 9th, 2004 08:30 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.