0

I am trying to get the Number for an Integer number (No Decimal exist), or the number part before the Decimal Point for a Decimal Number.

The example below should give 12345 as the answer. But it is giving it as 1234 (eating the 5 out)

            string isDecimalTypeNumbers = @"^(?<wholeNumberPart>[0-9]*)\.?[0-9]+?$";
            Regex pattern = new Regex(isDecimalTypeNumbers);
            Match match = pattern.Match("12345");
            if (match.Success)
            {
                string wholeNumberPartWithoutPlusMinusSign = match.Groups["wholeNumberPart"].Value;
                MessageBox.Show(wholeNumberPartWithoutPlusMinusSign);
            }
BeeGees
  • 451
  • 3
  • 10

2 Answers2

1
^(?<wholeNumberPart>[0-9]*)

captures the first part of the number

\.?

captures the decimal point if it exists

[0-9]+?$

captures the last number regardless of whether there is a decimal point

So as you can see the last bit captures the 5 leaving only 1234 as the wholeNumberPart.

I think this explains why the regex group extraction is giving you the wrong answer of 1234

openshac
  • 4,966
  • 5
  • 46
  • 77
  • thanx shac. But still why should (?[0-9]*) not capture the last digit 5, because after all 12345 is a whole number without any decimals. – BeeGees Feb 01 '20 at 06:37
  • 2
    If `[0-9]*` were to match `12345` then there'd be no digits left for `[0-9]+?` to match. As [@Xiaoy312's answer](https://stackoverflow.com/a/60014622/150605) says, `+?` is lazy but not optional, so `[0-9]+?` must match at least one digit. – Lance U. Matthews Feb 01 '20 at 06:45
  • Got it @bacon. Your explanation makes it clearer. Thanx. – BeeGees Feb 01 '20 at 06:56
  • Why does Regex give Match Success if Value String is Empty? – BeeGees Feb 01 '20 at 09:14
1
  • The decimal separator (\.?) is optional, so it may not match.
  • The fractional part ([0-9]+?) is not optional, but lazy, so it will still try to match.

So, what could happen is 1234 is consumed by the whole number part, and \.? doesnt match, but 5 is consumed by the fractional part.

You should make the decimal separator and the fractional part into one optional group:

@"^(?<wholeNumberPart>[0-9]*)(\.[0-9]+)?$"
Xiaoy312
  • 14,292
  • 1
  • 32
  • 44
  • Thanx Xiaoy. I tried this (the same as @AhmedAbdelhameed recommended) and it worked. Thanx. – BeeGees Feb 01 '20 at 06:43
  • Why does Regex give Match Success if Value String is Empty? – BeeGees Feb 01 '20 at 09:14
  • Just change the `[0-9]*` to `[0-9]+`. The `*` matches 0-to-many elements, so nothing is also a valid match. Replacing it with `+` will make it matches 1-to-many elements. – Xiaoy312 Feb 01 '20 at 18:05