Skip to content

Commit 98787c7

Browse files
committed
Improve support for locale settings in the Calculation Engine formatted number matcher
1 parent d029042 commit 98787c7

File tree

2 files changed

+10
-5
lines changed

2 files changed

+10
-5
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
1818
### Changed
1919

2020
- Improved handling for @ in Number Format Masks [PR #3344](https://github.com/PHPOffice/PhpSpreadsheet/pull/3344)
21+
- 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)
2122

2223
### Deprecated
2324

src/PhpSpreadsheet/Calculation/Engine/FormattedNumber.php

+9-5
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ public static function convertToNumberIfFormatted(string &$operand): bool
4848
*/
4949
public static function convertToNumberIfNumeric(string &$operand): bool
5050
{
51-
$value = preg_replace(['/(\d),(\d)/u', '/([+-])\s+(\d)/u'], ['$1$2', '$1$2'], trim($operand));
51+
$thousandsSeparator = preg_quote(StringHelper::getThousandsSeparator());
52+
$value = preg_replace(['/(\d)' . $thousandsSeparator . '(\d)/u', '/([+-])\s+(\d)/u'], ['$1$2', '$1$2'], trim($operand));
5253

5354
if (is_numeric($value)) {
5455
$operand = (float) $value;
@@ -87,7 +88,8 @@ public static function convertToNumberIfFraction(string &$operand): bool
8788
*/
8889
public static function convertToNumberIfPercent(string &$operand): bool
8990
{
90-
$value = preg_replace('/(\d),(\d)/u', '$1$2', $operand);
91+
$thousandsSeparator = preg_quote(StringHelper::getThousandsSeparator());
92+
$value = preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', $operand);
9193

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

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

128131
public static function currencyMatcherRegexp(): string
129132
{
130-
$quotedCurrencyCode = sprintf(self::CURRENCY_CONVERSION_LIST, preg_quote(StringHelper::getCurrencyCode()));
133+
$currencyCodes = sprintf(self::CURRENCY_CONVERSION_LIST, preg_quote(StringHelper::getCurrencyCode()));
134+
$decimalSeparator = preg_quote(StringHelper::getDecimalSeparator());
131135

132-
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';
136+
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';
133137
}
134138
}

0 commit comments

Comments
 (0)