-2

I would like to validate whether a string satisfy the following currency format with maximum 4 decimal places and could allow comma , regardless of culture and the comma could be at places of standard practice.

Eg:

2,000,000(valid)  
200000.0000(valid)  
200 (valid)  
200.00000(invalid)

How could it be done?

Arghya C
  • 9,805
  • 2
  • 47
  • 66
vincentsty
  • 2,963
  • 7
  • 34
  • 51
  • Check [**this**](http://stackoverflow.com/questions/9182858/validating-my-money). Here is [**another one**](http://stackoverflow.com/questions/2693832/best-way-to-validate-currency-input). If these did not help, a regular expression may be, is'nt ?! – Rohit416 Nov 06 '15 at 05:32
  • You get the decimal separator via `[CultureInfo].NumberFormat.NumberDecimalSeparator`. Now I'm sure there is a nice RegEx for that, but you might also be able to do it like `string[] parts = value.Split(new string[] {decimalSeparator}); bool isValid = parts.Length <= 1 || parts[1].Length <= 4;` – Corak Nov 06 '15 at 05:35
  • Regex `^\d+(\,\d+)*(\.\d{1,4})?$` might work for you. Demo https://regex101.com/r/lD4eZ5/1 – Arghya C Nov 06 '15 at 05:37

1 Answers1

5

You can do Regex match for your purpose.

The Regex below works for your specific examples. But, it'll accept comma , at random places. Demo here.

^\d+(\,\d+)*(\.\d{1,4})?$

A better Regex would be the following. Check the demo. Base Regex taken from this post.

^\$?(\d{1,3},(\d{3},)*\d{3}|\d+)(.\d{1,4})?$

Update

To answer comment - above Regex allows 0090. Try this one. Demo here.

^((([1-9]\d{0,2},(\d{3},)*\d{3}|[1-9]\d*)(.\d{1,4})?)|(0\.\d{1,4}))$

Update 2

C# usage

var currencyString = "1,234,456.7890";
var regex = @"^((([1-9]\d{0,2},(\d{3},)*\d{3}|[1-9]\d*)(.\d{1,4})?)|(0\.\d{1,4}))$";
var isValidCurency = Regex.IsMatch(currencyString, regex);

Update 3

As per OP, comma , is allowed at any place. Updated Regex with demo here.

^(([1-9]\d*(\,\d+)*(\.\d{1,4})?)|(0\.\d{1,4})|0)$

Update 4

Use this one. Demo HERE.

^((([1-9]\d{0,2}(,\d{3})*)(\.\d{1,4})?)|[1-9]\d*|(0\.\d{1,4})|0)$

Well, this :)

^((([1-9]\d{0,2}(,\d{3})*|[1-9]\d*)(\.\d{1,4})?)|[1-9]\d*|(0\.\d{1,4})|0)$
Community
  • 1
  • 1
Arghya C
  • 9,805
  • 2
  • 47
  • 66
  • it pass with the following: 0200 – vincentsty Nov 06 '15 at 06:15
  • How to use it in C#? Regex regex = new Regex(@"/^([1-9]\d{0,2},(\d{3},)*\d{3}|[1-9]\d*)(.\d{1,4})?$/gm"); this seems not working as expected. Neither do it work if i remove gm – vincentsty Nov 06 '15 at 06:47
  • Please see the updated answer and updated Regex. For single string you can ignore gm flags. – Arghya C Nov 06 '15 at 06:53
  • hi thanks for the feedback. But it doesnt work for this case. 1000,000 and 1,000000 – vincentsty Nov 06 '15 at 07:05
  • I didn't understand you'd allow comma at any place! See update 3. – Arghya C Nov 06 '15 at 07:23
  • Hmm. I think i did not explain it clearly. I mean that the update 2 validation pass for 1000,000 and 1,000000. What i would like to achieve is either the comma is allow in every 3 digit before decimal, or don't allow at all. eg: 1,000,000 (pass) 1000,000(fail) 1,000000(fail), 1000000(pass) – vincentsty Nov 06 '15 at 07:27
  • @vincentsty there was an mistake. Please see update 4 :) – Arghya C Nov 06 '15 at 07:50
  • hi 20000000.0000(fail). should pass – vincentsty Nov 06 '15 at 09:33
  • Different cultures have different decimal separators ([NumberFormatInfo.NumberDecimalSeparator](https://msdn.microsoft.com/library/system.globalization.numberformatinfo.numberdecimalseparator.aspx)) and thousand separators ([NumberFormatInfo.NumberGroupSeparator](https://msdn.microsoft.com/library/system.globalization.numberformatinfo.numbergroupseparator.aspx)) and users can even create their own custom ones. So I strongly suggest you to use the appropriate ways of finding them out and using them, instead of "guessing" where a `','` or `'.'` might be allowed or not. – Corak Nov 06 '15 at 09:51
  • @vincentsty I had already updated the answer. It works fine. Please check again (the last regex and link). – Arghya C Nov 06 '15 at 10:23
  • @Corak true. But the OP specifically wants a format irrespective of culture. Mentioned in the question. – Arghya C Nov 06 '15 at 10:24
  • @ArghyaC - Yes, and I argue that working on string representations of decimal values without taking the culture into consideration is not good for sanity in the long run. Even then, work with `CultureInfo.InvariantCulture`, which seems to be what OP want's to do implicitly. And even if it's really fixed, I'd argue that `string[] parts = value.Split('.'); bool isValid = parts.Length <= 1 || parts[1].Length <= 4;` is more readable than that RegEx. ^_^ – Corak Nov 06 '15 at 10:32
  • @Corak I agree on the Culture part and maintainability in long run. Apart from that, the code you gave is plain wrong. No offense, just try it once :) – Arghya C Nov 06 '15 at 10:55
  • @ArghyaC - wouldn't say "plain wrong". It works very well for the original question. It fails on checking "comma is allowed in every 3 digit before decimal, or don't allow at all", though (i.e. returns a false positive). – Corak Nov 06 '15 at 12:24
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/94431/discussion-between-arghya-c-and-corak). – Arghya C Nov 06 '15 at 12:33