Skip to content

Commit

Permalink
Number formatter update.
Browse files Browse the repository at this point in the history
Changelog excerpt:
- Added some limited support to the number formatter class for unformatting
  a formatted number.
  • Loading branch information
Maikuolan committed Feb 5, 2025
1 parent bd743fa commit 16f390e
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 7 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/php-cs-fixer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ jobs:

- name: PHP-CS-Fixer Check
run: |
php-cs-fixer fix -v --dry-run ./src --rules=@PSR12
php-cs-fixer fix -v --dry-run ./.tests --rules=@PSR12
php-cs-fixer fix -v --dry-run ./src --rules=@PSR12,-blank_line_after_opening_tag
php-cs-fixer fix -v --dry-run ./.tests --rules=@PSR12,-blank_line_after_opening_tag
45 changes: 45 additions & 0 deletions .tests/NumberFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,48 @@
echo 'Test failed: ' . $Case . ':L' . __LINE__ . '().' . PHP_EOL;
exit($ExitCode);
}

$Formats = [
'Arabic-1',
'Arabic-2',
'Arabic-3',
'Arabic-4',
'Bengali-1',
'Burmese-1',
'Fullwidth',
'Geez',
'India-1',
'India-2',
'India-3',
'India-4',
'India-5',
'India-6',
'Javanese',
'Kaktovik',
'Khmer-1',
'Lao-1',
'Latin-1',
'Latin-2',
'Latin-3',
'Latin-4',
'Latin-5',
'Mayan',
'Mongolian',
'Odia',
'Thai-1',
'Thai-2',
'Tibetan'
];

$ExitCode++;
foreach ($Formats as $Format) {
$Obj = new \Maikuolan\Common\NumberFormatter($Format);
foreach (['123456789', '987654321', '102030405060708090', '100', '1000', '10000'] as $Number) {
$Try = $Obj->format($Number);
$Compare = $Obj->unformat($Try);
if ($Compare !== $Number) {
echo 'Test failed: ' . $Case . ':L' . __LINE__ . '(). ' . $Compare . ' !== ' . $Number . ' (' . $Format . ')!' . PHP_EOL;
exit($ExitCode);
}
}
}
2 changes: 0 additions & 2 deletions .tests/OperationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,6 @@
}
}

echo $Out;

$ExitCode++;
if ($Out !== $Expected) {
echo 'Test failed: ' . $Case . ':L' . __LINE__ . '().' . PHP_EOL;
Expand Down
3 changes: 2 additions & 1 deletion Changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ found at:

=== Changes made since last versioned release ===

(none)
- [2025.05.02; Maikuolan]: Added some limited support to the number formatter
class for unformatting a formatted number.

=== Version/Release 2.12.3 ===
PATCH RELEASE.
Expand Down
49 changes: 48 additions & 1 deletion _docs/NumberFormatter.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- [NumberFormatter constructor.](#numberformatter-constructor)
- [format method.](#format-method)
- [getSetJSON method.](#getsetjson-method)
- [unformat method.](#unformat-method)
- [ConversionSet member.](#conversionset-member)
- [GroupSeparator member.](#groupseparator-member)
- [GroupSize member.](#groupsize-member)
Expand Down Expand Up @@ -226,6 +227,52 @@ Output:
["\u06f0","\u06f1","\u06f2","\u06f3","\u06f4","\u06f5","\u06f6","\u06f7","\u06f8","\u06f9"]
```


#### unformat method.

Unformats the formatted number according to predefined patterns and lookup tables.

*Warning: Doesn't work for ALL formats (..yet), won't work for fractions (only intended for whole numbers), and other data (e.g., decimal separators, thousands separators) will be disregarded entirely.*

```PHP
$Obj = new \Maikuolan\Common\NumberFormatter('Arabic-2');
$Try = $Obj->format('12345678987654321');
echo $Try . PHP_EOL;
$Try = $Obj->unformat($Try);
echo $Try . PHP_EOL;

$Obj = new \Maikuolan\Common\NumberFormatter('India-2');
$Try = $Obj->format('12345678987654321');
echo $Try . PHP_EOL;
$Try = $Obj->unformat($Try);
echo $Try . PHP_EOL;

$Obj = new \Maikuolan\Common\NumberFormatter('Geez');
$Try = $Obj->format('12345678987654321');
echo $Try . PHP_EOL;
$Try = $Obj->unformat($Try);
echo $Try . PHP_EOL;

$Obj = new \Maikuolan\Common\NumberFormatter('Kaktovik');
$Try = $Obj->format('12345678987654321');
echo $Try . PHP_EOL;
$Try = $Obj->unformat($Try);
echo $Try . PHP_EOL;
```

Output:

```
١٢٬٣٤٥٬٦٧٨٬٩٨٧٬٦٥٤٬٣٢١
12345678987654321
१२,३४,५६,७८,९८,७६,५४,३२१
12345678987654321
፼፳፫፻፵፭፼፷፯፻፹፱፼፹፯፻፷፭፼፵፫፻፳፩
12345678987654321
�������������
12345678987654321
```

#### ConversionSet member.

```PHP
Expand Down Expand Up @@ -547,4 +594,4 @@ Base 36: a.i000 ~ 74.9000
---


Last Updated: 26 June 2024 (2024.06.26).
Last Updated: 5 February 2025 (2025.02.05).
91 changes: 90 additions & 1 deletion src/NumberFormatter.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/**
* Number formatter (last modified: 2024.06.26).
* Number formatter (last modified: 2025.02.05).
*
* This file is a part of the "common classes package", utilised by a number of
* packages and projects, including CIDRAM and phpMussel.
Expand Down Expand Up @@ -1058,6 +1058,63 @@ class NumberFormatter extends CommonAbstract
'z' => '35'
];

/**
* @var array Lookup table for unformatting a number.
*/
private $UnformatTable = [
'0' => ['٠', '۰', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'Z', ''],
'1' => ['١', '۱', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
'2' => ['٢', '۲', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
'3' => ['٣', '۳', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
'4' => ['٤', '۴', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
'5' => ['٥', '۵', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
'6' => ['٦', '۶', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
'7' => ['٧', '۷', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
'8' => ['٨', '۸', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''],
'9' => ['٩', '۹', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
];

/**
* @var array Patterns for unformatting a number.
*/
private $UnformatPattern = [
'~(?<!一|二|三|四|五|六|七|八|九|十|百|千)(十|百|千|拾|万|億|兆|京|垓)~' => '1\1',
'~^(፻|፼|十|百|千|拾|万|億|兆|京|垓|௰|௱|௲)~' => '1\1',
'~(፻|፼)(?!፲|፳|፴|፵|፶|፷|፸|፹|፺|\d)~' => '\1Z',
'~(፻[\dZ]|፼[\dZ])(?!፩|፪|፫|፬|፭|፮|፯|፰|፱|\d)~' => '\1Z',
'~(፲|፳|፴|፵|፶|፷|፸|፹|፺)(?!፩|፪|፫|፬|፭|፮|፯|፰|፱)~' => '\1Z',
'~(十|拾)$~' => '0',
'~(፻|百)$~' => '00',
'~千$~' => '000',
'~፼$~' => '0000'
];

/**
* @var array Lookup table for unformatting a base-20 number.
*/
private $UnformatTableKakMay = [
'0' => ['𝋀', '𝋠'],
'1' => ['𝋁', '𝋡'],
'2' => ['𝋂', '𝋢'],
'3' => ['𝋃', '𝋣'],
'4' => ['𝋄', '𝋤'],
'5' => ['𝋅', '𝋥'],
'6' => ['𝋆', '𝋦'],
'7' => ['𝋇', '𝋧'],
'8' => ['𝋈', '𝋨'],
'9' => ['𝋉', '𝋩'],
'a' => ['𝋊', '𝋪'],
'b' => ['𝋋', '𝋫'],
'c' => ['𝋌', '𝋬'],
'd' => ['𝋍', '𝋭'],
'e' => ['𝋎', '𝋮'],
'f' => ['𝋏', '𝋯'],
'g' => ['𝋐', '𝋰'],
'h' => ['𝋑', '𝋱'],
'i' => ['𝋒', '𝋲'],
'j' => ['𝋓', '𝋳'],
];

/**
* Constructor.
*
Expand Down Expand Up @@ -1384,6 +1441,38 @@ public function getSetJSON(string $Set = ''): string
return isset($this->{$Set}) ? json_encode($this->{$Set}) : '[]';
}

/**
* Unformats the formatted number according to predefined patterns and lookup
* tables. Warning: Doesn't work for all formats (..yet), won't work for
* fractions (only intended for whole numbers), and other data (e.g., decimal
* separators, thousands separators) will be disregarded entirely.
*
* @param string $Number The number to unformat.
* @return string The unformatted number (returned as string rather than as an
* integer or a float in order to retain decimal precision).
*/
public function unformat(string $Number): string
{
if (preg_match('~\D~', $Number)) {
foreach ($this->UnformatPattern as $Pattern => $Replacement) {
$Number = preg_replace($Pattern, $Replacement, $Number);
}
foreach ($this->UnformatTable as $Replacement => $Lookup) {
$Number = str_replace($Lookup, $Replacement, $Number);
}
$KakMay = $Number;
foreach ($this->UnformatTableKakMay as $Replacement => $Lookup) {
$KakMay = str_replace($Lookup, $Replacement, $KakMay);
}
if ($KakMay !== $Number) {
$Number = base_convert(preg_replace('~[^\da-j]~', '', $KakMay), 20, 10);
} else {
$Number = preg_replace('~\D~', '', $Number);
}
}
return preg_replace('~^0+~', '', $Number);
}

/**
* Prepare to convert a fraction.
*
Expand Down

0 comments on commit 16f390e

Please sign in to comment.