Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate currency amount using regular expressions in JavaScript [duplicate]

Possible Duplicate:
What's a C# regular expression that'll validate currency, float or integer?

How can I validate currency amount using regular expressions in JavaScript?

Decimals separator: ,

Tens, hundreds, etc. separator: .

Pattern: ###.###.###,##

Examples of valid amounts:

1
1234
123456

1.234
123.456
1.234.567

1,23
12345,67
1234567,89

1.234,56
123.456,78
1.234.567,89

EDIT

I forgot to mention that the following pattern is also valid: ###,###,###.##

like image 682
Diogo Cardoso Avatar asked May 31 '11 16:05

Diogo Cardoso


2 Answers

Based solely on the criteria you gave, this is what I came up with.

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

http://refiddle.com/18u

It is ugly, and it will only get worse as you find more cases that need to be matched. You'd be well served to find and use some validation library rather than try to do this all yourself, especially not in a single regular expression.

Updated to reflect added requirements.


Updated again in regard to comment below.

It would match 123.123,123 (three trailing digits instead of two) because it would accept either comma or period as both the thousands and decimal separators. To fix that, I've now essentially doubled up the expression; either it matches the whole thing with commas for separators and a period as the radix point, or it matches the whole thing with periods for separators and a comma as the radix point.

See what I mean about it getting messier? (^_^)


Here's the verbose explanation:

(?:^           # beginning of string
  \d{1,3}      # one, two, or three digits
  (?:
    \.?        # optional separating period
    \d{3}      # followed by exactly three digits
  )*           # repeat this subpattern (.###) any number of times (including none at all)
  (?:,\d{2})?  # optionally followed by a decimal comma and exactly two digits
$)             # End of string.
|              # ...or...
(?:^           # beginning of string
  \d{1,3}      # one, two, or three digits
  (?:
    ,?         # optional separating comma
    \d{3}      # followed by exactly three digits
  )*           # repeat this subpattern (,###) any number of times (including none at all)
  (?:\.\d{2})? # optionally followed by a decimal perioda and exactly two digits
$)             # End of string.

One thing that makes it look more complicated is all the ?: in there. Normally a regular expression captures (returns matches for) all of the subpatterns too. All ?: does is say to not bother to capture the subpattern. So technically, the full thing would still match your entire string if you took all of the ?: out, which looks a bit clearer:

/(^\d{1,3}(\.?\d{3})*(,\d{2})?$)|(^\d{1,3}(,?\d{3})*(\.\d{2})?$)/

Also, regular-expressions.info is a great resource.

like image 142
Wiseguy Avatar answered Nov 19 '22 07:11

Wiseguy


This works for all your examples:

/^(?:\d+(?:,\d{3})*(?:\.\d{2})?|\d+(?:\.\d{3})*(?:,\d{2})?)$/

As a verbose regex (not supported in JavaScript, though):

^              # Start of string
(?:            # Match either...
 \d+           # one or more digits
 (?:,\d{3})*   # optionally followed by comma-separated threes of digits
 (?:\.\d{2})?  # optionally followed by a decimal point and exactly two digits
|              # ...or...
 \d+           # one or more digits
 (?:\.\d{3})*  # optionally followed by point-separated threes of digits
 (?:,\d{2})?   # optionally followed by a decimal comma and exactly two digits
)              # End of alternation
$              # End of string.
like image 27
Tim Pietzcker Avatar answered Nov 19 '22 07:11

Tim Pietzcker