Skip to content

Commit edc003a

Browse files
committed
Improved handling of @ format mask
Note that it still doesn't work fully if in section 4
1 parent ad0b68c commit edc003a

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

src/PhpSpreadsheet/Style/NumberFormat/Formatter.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
class Formatter
1111
{
12+
private const SYMBOL_AT = '/@(?=(?:[^"]*"[^"]*")*[^"]*\Z)/miu';
13+
private const SECTION_SPLIT = '/;(?=(?:[^"]*"[^"]*")*[^"]*\Z)/miu';
14+
1215
/**
1316
* @param mixed $value
1417
* @param mixed $val
@@ -112,7 +115,13 @@ public static function toFormattedString($value, $format, $callBack = null)
112115
if (is_bool($value)) {
113116
return $value ? Calculation::getTRUE() : Calculation::getFALSE();
114117
}
115-
// For now we do not treat strings although section 4 of a format code affects strings
118+
// For now we do not treat strings in sections, although section 4 of a format code affects strings
119+
// Process a single block format code containing @ for text substitution
120+
if (preg_match(self::SECTION_SPLIT, $format) === 0 && preg_match(self::SYMBOL_AT, $format) === 1) {
121+
return str_replace('"', '', preg_replace(self::SYMBOL_AT, (string) $value, $format) ?? '');
122+
}
123+
124+
// If we have a text value, return it "as is"
116125
if (!is_numeric($value)) {
117126
return (string) $value;
118127
}
@@ -138,7 +147,7 @@ function ($matches) {
138147
$format = (string) preg_replace('/(\\\(((.)(?!((AM\/PM)|(A\/P))))|([^ ])))(?=(?:[^"]|"[^"]*")*$)/ui', '"${2}"', $format);
139148

140149
// Get the sections, there can be up to four sections, separated with a semi-colon (but only if not a quoted literal)
141-
$sections = preg_split('/(;)(?=(?:[^"]|"[^"]*")*$)/u', $format) ?: [];
150+
$sections = preg_split(self::SECTION_SPLIT, $format) ?: [];
142151

143152
[$colors, $format, $value] = self::splitFormat($sections, $value);
144153

tests/data/Style/NumberFormat.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,27 @@
373373
'test',
374374
'_-€* #,##0.00_-;"-€"* #,##0.00_-;_-€* -??_-;_-@_-',
375375
],
376+
// String masks (ie. @)
377+
[
378+
'World',
379+
'World',
380+
'@',
381+
],
382+
[
383+
'Hello World',
384+
'World',
385+
'Hello @',
386+
],
387+
[
388+
'Hello World',
389+
'World',
390+
'"Hello "@',
391+
],
392+
[
393+
'Meet me @ The Boathouse @ 16:30',
394+
'The Boathouse',
395+
'"Meet me @ "@" @ 16:30"',
396+
],
376397
// Named colours
377398
// Simple color
378399
[

0 commit comments

Comments
 (0)