Skip to content

Commit

Permalink
Improve support for locale settings in the Calculation Engine formatt…
Browse files Browse the repository at this point in the history
…ed number matcher
  • Loading branch information
MarkBaker committed Feb 17, 2023
1 parent d029042 commit 3d7964f
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
### Changed

- Improved handling for @ in Number Format Masks [PR #3344](https://github.com/PHPOffice/PhpSpreadsheet/pull/3344)
- Improved support for locale settings and currency codes when matching formatted strings to numerics in the Calculation Engine [PR #3373](https://github.com/PHPOffice/PhpSpreadsheet/pull/3373) and [PR #3374](https://github.com/PHPOffice/PhpSpreadsheet/pull/3374)

### Deprecated

Expand Down
18 changes: 13 additions & 5 deletions src/PhpSpreadsheet/Calculation/Engine/FormattedNumber.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ public static function convertToNumberIfFormatted(string &$operand): bool
*/
public static function convertToNumberIfNumeric(string &$operand): bool
{
$value = preg_replace(['/(\d),(\d)/u', '/([+-])\s+(\d)/u'], ['$1$2', '$1$2'], trim($operand));
$thousandsSeparator = preg_quote(StringHelper::getThousandsSeparator());
$value = preg_replace(['/(\d)' . $thousandsSeparator . '(\d)/u', '/([+-])\s+(\d)/u'], ['$1$2', '$1$2'], trim($operand));
$decimalSeparator = preg_quote(StringHelper::getDecimalSeparator());
$value = preg_replace(['/(\d)' . $decimalSeparator . '(\d)/u', '/([+-])\s+(\d)/u'], ['$1.$2', '$1$2'], $value ?? '');

if (is_numeric($value)) {
$operand = (float) $value;
Expand Down Expand Up @@ -87,7 +90,10 @@ public static function convertToNumberIfFraction(string &$operand): bool
*/
public static function convertToNumberIfPercent(string &$operand): bool
{
$value = preg_replace('/(\d),(\d)/u', '$1$2', $operand);
$thousandsSeparator = preg_quote(StringHelper::getThousandsSeparator());
$value = preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', trim($operand));
$decimalSeparator = preg_quote(StringHelper::getDecimalSeparator());
$value = preg_replace(['/(\d)' . $decimalSeparator . '(\d)/u', '/([+-])\s+(\d)/u'], ['$1.$2', '$1$2'], $value ?? '');

$match = [];
if ($value !== null && preg_match(self::STRING_REGEXP_PERCENT, $value, $match, PREG_UNMATCHED_AS_NULL)) {
Expand All @@ -110,7 +116,8 @@ public static function convertToNumberIfPercent(string &$operand): bool
public static function convertToNumberIfCurrency(string &$operand): bool
{
$currencyRegexp = self::currencyMatcherRegexp();
$value = preg_replace('/(\d),(\d)/u', '$1$2', $operand);
$thousandsSeparator = preg_quote(StringHelper::getThousandsSeparator());
$value = preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', $operand);

$match = [];
if ($value !== null && preg_match($currencyRegexp, $value, $match, PREG_UNMATCHED_AS_NULL)) {
Expand All @@ -127,8 +134,9 @@ public static function convertToNumberIfCurrency(string &$operand): bool

public static function currencyMatcherRegexp(): string
{
$quotedCurrencyCode = sprintf(self::CURRENCY_CONVERSION_LIST, preg_quote(StringHelper::getCurrencyCode()));
$currencyCodes = sprintf(self::CURRENCY_CONVERSION_LIST, preg_quote(StringHelper::getCurrencyCode()));
$decimalSeparator = preg_quote(StringHelper::getDecimalSeparator());

return '~^(?:(?: *(?<PrefixedSign>[-+])? *(?<PrefixedCurrency>[' . $quotedCurrencyCode . ']) *(?<PrefixedSign2>[-+])? *(?<PrefixedValue>[0-9]+\.?[0-9*]*(?:E[-+]?[0-9]*)?) *)|(?: *(?<PostfixedSign>[-+])? *(?<PostfixedValue>[0-9]+\.?[0-9]*(?:E[-+]?[0-9]*)?) *(?<PostCurrency>[' . $quotedCurrencyCode . ']) *))$~ui';
return '~^(?:(?: *(?<PrefixedSign>[-+])? *(?<PrefixedCurrency>[' . $currencyCodes . ']) *(?<PrefixedSign2>[-+])? *(?<PrefixedValue>[0-9]+[' . $decimalSeparator . ']?[0-9*]*(?:E[-+]?[0-9]*)?) *)|(?: *(?<PostfixedSign>[-+])? *(?<PostfixedValue>[0-9]+' . $decimalSeparator . '?[0-9]*(?:E[-+]?[0-9]*)?) *(?<PostCurrency>[' . $currencyCodes . ']) *))$~ui';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,14 @@ public function providerPercentages(): array
'permutation_77' => ['-2.5E-8', '-%2.50E-06'],
'permutation_78' => [' - % 2.50 E -06 ', ' - % 2.50 E -06 '],
'permutation_79' => ['-2.5E-8', ' - % 2.50E-06 '],
'permutation_80' => [' - % 2.50E- 06 ', ' - % 2.50E- 06 '],
'permutation_80' => ['-2.5E-8', ' - % 2.50E- 06 '],
'permutation_81' => [' - % 2.50E - 06 ', ' - % 2.50E - 06 '],
'permutation_82' => ['-2.5E-6', '-2.5e-4%'],
'permutation_83' => ['200', '2e4%'],
'permutation_84' => ['-2.5E-8', '-%2.50e-06'],
'permutation_85' => [' - % 2.50 e -06 ', ' - % 2.50 e -06 '],
'permutation_86' => ['-2.5E-8', ' - % 2.50e-06 '],
'permutation_87' => [' - % 2.50e- 06 ', ' - % 2.50e- 06 '],
'permutation_87' => ['-2.5E-8', ' - % 2.50e- 06 '],
'permutation_88' => [' - % 2.50e - 06 ', ' - % 2.50e - 06 '],
];
}
Expand Down

0 comments on commit 3d7964f

Please sign in to comment.