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 98787c7
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 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
14 changes: 9 additions & 5 deletions src/PhpSpreadsheet/Calculation/Engine/FormattedNumber.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ 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));

if (is_numeric($value)) {
$operand = (float) $value;
Expand Down Expand Up @@ -87,7 +88,8 @@ 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', $operand);

$match = [];
if ($value !== null && preg_match(self::STRING_REGEXP_PERCENT, $value, $match, PREG_UNMATCHED_AS_NULL)) {
Expand All @@ -110,7 +112,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 +130,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';
}
}

0 comments on commit 98787c7

Please sign in to comment.