12

Been out of the regex game for a while. Trying to come up with something that will allow the user to enter a money value either with/without dollar sign or with/without commas. For example, all the of the following values should be valid:

5
5.1
5.10
$5
500,000
500,000.1
500,000.10
$100,000,000.50
etc....

Could someone please help me out?

1

6 Answers 6

23

This should work:

isValid = str.search(/^\$?[\d,]+(\.\d*)?$/) >= 0;

A little more strict with comma placement (would reject 3,2.10, for example):

isValid = str.search(/^\$?\d+(,\d{3})*(\.\d*)?$/) >= 0;

To get a number out of it:

if(isValid) {
  var num = Number(str.replace(/[\$,]/g, ''));
  ...
}
Sign up to request clarification or add additional context in comments.

9 Comments

Instead of string.search(regex)>-1, just use regex.test(string)
Error in your first regex. Regex evaluates "10." as true. Use + instead of * to mean 'at least 1'. Try isValid = str.search(/^\$?[\d,]+(\.\d+)?$/) >= 0;
@MatthewB.Gray that's not an error. I would consider "10." to be valid. The question does not specify one way or the other.
Quick note I noticed when testing this, I would change the (\.\d*)? to be (\.\d{2})? since cents pretty much always goes to hundredths and no further. Also the first \d+ could be \d{1,3}, so it doesn't just match all numbers before a comma.
@Zorpix thanks for the input. the \d+ was also to allow numbers with no comma at all, which is how most people actually type them. if you want to be even more strict about comma placement, without actually requiring commas, you could use (\d+|\d{1,3}(,\d{3})*). This regex also doesn't accept decimal-only numbers, like .01
|
2

I didn't Test Driven Developement, TDD, for this one using the Qunit framework.

TDD overview http://net.tutsplus.com/tutorials/javascript-ajax/test-driven-javascript-development-in-practice/

1st: Write tests.

2nd: Watch tests fail.

3rd: Make test pass.

4th: Refactor.

var moneyTest_RE = /^\$?\d+((,\d{3})+)?(\.\d+)?$/;
test("test money format for valid values", function () {
    var moneyArr = ["5","5.1","5.10","$5","500,000","500,000.1","500,000.10","$100,000,000.50", "500,000,100" ];
    var i = moneyArr.length;

    while( i-- ){
        equal( moneyTest_RE.test( moneyArr[ i ] ), true, moneyArr[ i ] + " didn't match completely." );
    }
});
test("test money format for invalid values", function () {
    var moneyArr = ["5..","$$5.1",".5.10","$5.2.","50,0,000",",500,000.1","500,000,10,","$1,00,000,000.50", "500,000,10"];
    var i = moneyArr.length;

    while( i-- ){
        equal( moneyTest_RE.test( moneyArr[ i ] ), false, moneyArr[ i ] + " didn't match completely." );
    }
});

Here's one possible solution to your problem.

var moneyTest_RE = /^\$?\d+((,\d{3})+)?(\.\d+)?$/;  

Demo here: http://jsfiddle.net/vpyV6/

I forgot to refactor though.

Comments

2

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

This one took a while, but I finally got something fully functional. It allows for cases such as 100.00, .35, $1.35, etc. While excluding entries with misplaced commas, too many numbers in between or before commas, or too many numbers after the decimal point.

You can play around with it here

Comments

0
var currencyRegex = /^[$£€]\d+(?:\.\d\d)*$/g;

Example: $10 or £10 0r €10 but if you use simple 10 this will be wrong

Comments

0

Perhaps this? https://regex101.com/r/xBct9E/1

(\$?(:?\d+,?.?)+)

Also, https://regex101.com/r/xBct9E/3 ; a longer version that doesn't match numbers like 123,45.4.3

^(\$?(:?\d+,?)+(?:.?\d+)?)$

3 Comments

what more do you want me to post?
Thanks, what you added in the edit shortly after my comment from 2012 was enough - I'm deleting the no longer applicable comment. I didn't downvote, that happened somewhen last December. Maybe your answer was downvoted because it doesn't use JS regex literal syntax, or because it allows : characters, or because it allows .s to immediately follow ,s?
ah, not devoted enough to fix the dots and commas thing, but the : thing was a bug which is now fixed!
0

To handle most of inputs (including cases with ,):

const inputValue = '1,999.50'
const inputValueNoSpace = inputValue.replace(/\s+/igm, '')
const inputValueEnglish = inputValueNoSpace.replace(/(^[0-9,]*),(\d{1,2}$)/igm, "$1.$2").replace(',', '')

> inputValueEnglish
← '1999.50'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.