简体   繁体   中英

Regex for decimals with maximum length

I'm not sure if this is possible with regex. I'll try to use regex, but if not possible I'll switch to a double validation.

My database (postgresql) accepts decimal as 15,6 (Maximum of 15 digits with a maximum of 6 decimals), so if I have 10 integer digits, I can have 5 decimals digits. The decimal separator is ignored.

I currently have this regex (Comma is the decimal separator):

^\d{1,15}(\,\d{1,6})?$

It does not verify the total length, only the numbers to the left. But since the user can also type dots (thousands separator), I have this monster:

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

This one does not accept more than 3 decimals. I can edit this one to accept 6 decimais, but I still can't validate the total length.

Is it possible to verify the total length of the number? Ignoring the dots and comma.

The regex should accept:

1234567890,123456

1.234.567.890,123456

And of course any other middle values:

1.234,12 , 1,0 , 1 ...

Just throwing this out as an alternative. In my opinion you shouldn't use a Regex in this case. Why? Because the Regex that will actually match the question won't be easy to understand.

Much simpler solutions exist for the problem. Take for example this:

var input = "1.234.567.890,123456";
var input2 = Regex.Replace(input, @"[^\d,]+", "");

var split = input2.Split(',');
var totalLength = split[0].Length + split[1].Length;

Nothing fancy. But it works, unlike the other solutions provided until now.

But what about different culture settings? Different cultures use different thousand separators. That's where something like Double.TryParse can come in:

var input = "1.234.567.890,123456";

var style = NumberStyles.Number;
var culture = CultureInfo.CreateSpecificCulture("nl-NL");

double result;
if (double.TryParse(input, style, culture, out result))
{
    Console.WriteLine("It worked!");
}
else
{
    Console.WriteLine("Not valid");
}

The above works because the nl-NL culture uses the format. Set it to en-US and it will fail.

Neither really use a Regex to get the job done, but they can still produce the desired result.

I think you need

^(?:\d{1,3}(?:\.\d{3}){0,4}|\d{1,15})(?:,\d{1,6})?$

See the regex demo

The integer part only allows 1 to 15 digits (or 5 groups of 3-digit chunks separated with . digit grouping symbol), and optionally followed with a comma and 1 to 6 decimal digits.

  • ^ - start of string
  • (?:\\d{1,3}(?:\\.\\d{3}){0,4}|\\d{1,15}) - 2 alternatives:
    • \\d{1,3}(?:\\.\\d{3}){0,4} - 1 to 3 digits, followed with 0 to 4 sequences of a dot ( \\. ) and 3 digits ( \\d{3} )
    • | - or
    • \\d{1,15} - 1 to 15 digits
  • (?:,\\d{1,6})? - optional sequence (1 or 0 occurrences) of a comma followed with 1 to 6 digits
  • $ - end of string

试试这个: ^[\\d\\.\\,]{1,15}([\\.\\,]\\d{0,6})?$

^(\d{0,15})([\.\,]\d{0,6})?$
  • Group 1:
    any number with max length = 15
  • group 2:
    any number with max length of two, preceded by , or .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM