Fildor
Fildor

Reputation: 16104

Regex match depending on lookbehind match

I need to match these values:

(First approach to a regex that roughly does what I want)

\d+([.,]\d{3})*[.,]\d{2}

like

24,56
24.56
1.234,56
1,234.56
1234,56
1234.56

but I need to not match

1.234.56
1,234,56

So somehow I need to check the last occurrence of "." or "," to not be the same as the previous "." or ",".

Background: Amounts shall be matched in English and German format with (optional) 1000-Separators.

But even with help of regex101 I completely fail at coming up with a correctly working look-behind. Any suggestions are highly appreciated.

UPDATE

Based on the answers I got so far, I came up with this (demo):

\d{1,3}(?:([\.,'])?\d{3})*(?!\1)[\.,\s]\d{2}

But it matches for example 1234.567,23 which is not desirable.

Upvotes: 2

Views: 52

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627022

You may capture the digit grouping symbol and use a negative lookahead with a backreference to restrict the decimal separator:

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

See the regex demo

Group 1 will contain the last value of the digit grouping symbol and (?!\1)[.,] will match the other symbol.

Details:

  • ^ - start of string
  • (?:\d+|\d{1,3}(?:([.,])\d{3})*) - either of the two alternatives:
    • \d+ - 1+ digits
    • | - or
    • \d{1,3} - 1 to 3 digits,
    • (?:([.,])\d{3})* - zero or more sequences of:
      • ([.,]) - Group 1 capturing . or ,
      • \d{3} - 3 digits
  • (?!\1)[.,] - a . or , but not equal to what was last captured with ([.,]) pattern above
  • \d{2} - 2 digits
  • $ - end of string.

Upvotes: 2

Thomas Ayoub
Thomas Ayoub

Reputation: 29451

You can use

^\d+(([.,])\d{3})*(?!\2)[.,]\d{2}$

live demo

Upvotes: 2

Related Questions