"958.31" * - "1.234,56" => "1234.56" * - "1,234.56" => "1234.56" * - "1234" => "1234" * * Based on ImportProcessor::normalizeDecimal() */ public static function normalize(?string $raw): ?string { if ($raw === null) { return null; } // Keep digits, comma, dot, and minus to detect separators $s = preg_replace('/[^0-9,\.-]/', '', $raw) ?? ''; $s = trim($s); if ($s === '') { return null; } $lastComma = strrpos($s, ','); $lastDot = strrpos($s, '.'); // Determine decimal separator by last occurrence $decimalSep = null; if ($lastComma !== false || $lastDot !== false) { if ($lastComma === false) { $decimalSep = '.'; } elseif ($lastDot === false) { $decimalSep = ','; } else { $decimalSep = $lastComma > $lastDot ? ',' : '.'; } } // Remove all thousand separators and unify decimal to '.' if ($decimalSep === ',') { // Remove all dots (thousand separators) $s = str_replace('.', '', $s); // Replace last comma with dot $pos = strrpos($s, ','); if ($pos !== false) { $s[$pos] = '.'; } // Remove any remaining commas (unlikely) $s = str_replace(',', '', $s); } elseif ($decimalSep === '.') { // Remove all commas (thousand separators) $s = str_replace(',', '', $s); // Dot is already decimal separator } else { // No decimal separator: remove commas/dots entirely $s = str_replace([',', '.'], '', $s); } // Handle negative numbers $s = ltrim($s, '+'); $neg = false; if (str_starts_with($s, '-')) { $neg = true; $s = ltrim($s, '-'); } // Remove any stray minus signs $s = str_replace('-', '', $s); if ($neg) { $s = '-' . $s; } return $s; } }