Reputation: 27689
https://www.tehplayground.com/KWmxySzbC9VoDvP9
Why is the first string matched?
$list = [
'3928.3939392', // Should not be matched
'4.239,99',
'39',
'3929',
'2993.39',
'393993.999'
];
foreach($list as $str){
preg_match('/^(?<![\d.,])-?\d{1,3}(?:[,. ]?\d{3})*(?:[^.,%]|[.,]\d{1,2})-?(?![\d.,%]|(?: %))$/', $str, $matches);
print_r($matches);
}
Array
(
[0] => 3928.3939392
)
Array
(
[0] => 4.239,99
)
Array
(
[0] => 39
)
Array
(
[0] => 3929
)
Array
(
[0] => 2993.39
)
Array
(
)
Upvotes: 1
Views: 37
Reputation: 626920
You seem to want to match the numbers as standalone strings, and thus, you do not need the lookarounds, you only need to use anchors.
You may use
^-?(?:\d{1,3}(?:[,. ]\d{3})*|\d*)(?:[.,]\d{1,2})?$
See the regex demo
Details
^
- start of string-?
- an optional -
(?:
- start of a non-capturing alternation group:
\d{1,3}(?:[,. ]\d{3})*
- 1 to 3 digits, followed with 0+ sequences of ,
, .
or space and then 3 digits|
- or\d*
- 0+ digits)
- end of the group(?:[.,]\d{1,2})?
- an optional sequence of .
or ,
followed with 1 or 2 digits$
- end of string.Upvotes: 2