clarkk clarkk - 4 months ago 13
PHP Question

regexp - match numbers with two decimals and thousand seperator

http://www.tehplayground.com/#0qrTOzTh3

$inputs = array(
'2', // no match
'29.2', // no match
'2.48',
'8.06.16', // no match
'-2.41',
'-.54', // no match
'4.492', // no match
'4.194,32',
'39,299.39',
'329.382,39',
'-188.392,49',
'293.392,193', // no match
'-.492.183,33', // no match
'3.492.249,11',
'29.439.834,13',
'-392.492.492,43'
);

$number_pattern = '-?(?:[0-9]|[0-9]{2}|[0-9]{3}[\.,]?)?(?:[0-9]|[0-9]{2}|[0-9]{3})[\.,][0-9]{2}(?!\d)';

foreach($inputs as $input){
preg_match_all('/'.$number_pattern.'/m', $input, $matches);
print_r($matches);
}

Answer

It seems you are looking for

$number_pattern = '-?(?<![\d.,])\d{1,3}(?:[,.]\d{3})*[.,]\d{2}(?![\d.])';

See the PHP demo and a regex demo.

The anchors are not used, there are lookarounds on both sides of the pattern instead.

Pattern details:

  • -? - an optional hyphen
  • (?<![\d.,]) - there cannot be a digit, comma or dot befire the current location -\d{1,3} - 1 to 3 digits
  • (?:[,.]\d{3})* - zero or more sequences of a comma or dot followed with 3 digits
  • [.,] - a comma or dot
  • \d{2} - 2 digits that are
  • (?![\d.]) - not followed with a digit or dot.

Note in PHP, you do not need to specify the /m MULTILINE mode and use the $ end of string anchor,

preg_match_all('/'.$number_pattern.'/', $input, $matches);

is enough to match the numbers you need in larger texts.

If you need to match them as standalone strings, use a simpler

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

See the regex demo.