[bug-65644] Improved regex for Excel accounting formats. Thanks to Adam DeSapio

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1894386 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2021-10-19 18:25:33 +00:00
parent 67008b3114
commit 77786178ea
3 changed files with 24 additions and 1 deletions

View File

@ -108,7 +108,7 @@ public class CellFormatPart {
" \\s*(-?[0-9]+(?:\\.[0-9]*)?)\\s* # The constant to test against\n";
// A currency symbol / string, in a specific locale
String currency = "(\\[\\$.{0,3}-[0-9a-f]{3}\\])";
String currency = "(\\[\\$.{0,3}(-[0-9a-f]{3,4})?\\])";
String color =
"\\[(black|blue|cyan|green|magenta|red|white|yellow|color [0-9]+)\\]";
@ -307,6 +307,9 @@ public class CellFormatPart {
if (currencyPart.startsWith("[$-")) {
// Default $ in a different locale
currencyRepl = "$";
} else if (!currencyPart.contains("-")) {
// Accounting formats such as USD [$USD]
currencyRepl = currencyPart.substring(2, currencyPart.indexOf("]"));
} else {
currencyRepl = currencyPart.substring(2, currencyPart.lastIndexOf('-'));
}

View File

@ -940,12 +940,20 @@ class TestCellFormat {
// French style accounting, euro sign comes after not before
String formatFR = "_-#,##0* [$"+euro+"-40C]_-;\\-#,##0* [$"+euro+"-40C]_-;_-\"-\"??* [$"+euro+"-40C] _-;_-@_-";
// R English (South Africa) style accounting, R currency symbol and 4-digit locale specifier
String formatSA = "_-[$R-1C09]* #,##0_-;\\-[$R-1C09]* #,##0_-;_-[$R-1C09]* \"-\"??_-;_-@_-";
// USD style accounting, USD currency symbol without -xxx or -xxxx locale specifier
String formatUSD = "_([$USD]\\ * #,##0_);_([$USD]\\ * \\(#,##0\\);_([$USD]\\ * \"-\"??_);_(@_)";
// Has +ve, -ve and zero rules
CellFormat cfDft = CellFormat.getInstance(formatDft);
CellFormat cfUS = CellFormat.getInstance(formatUS);
CellFormat cfUK = CellFormat.getInstance(formatUK);
CellFormat cfFR = CellFormat.getInstance(formatFR);
CellFormat cfSA = CellFormat.getInstance(formatSA);
CellFormat cfUSD = CellFormat.getInstance(formatUSD);
// For +ve numbers, should be Space + currency symbol + spaces + whole number with commas + space
// (Except French, which is mostly reversed...)
assertEquals(" $ 12 ", cfDft.apply(12.33).text);
@ -953,22 +961,34 @@ class TestCellFormat {
assertEquals(" "+pound+" 12 ", cfUK.apply(12.33).text);
assertEquals(" 12 "+euro+" ", cfFR.apply(12.33).text);
assertEquals(" R 12 ", cfSA.apply(Double.valueOf(12.33)).text);
assertEquals(" USD 12 ", cfUSD.apply(Double.valueOf(12.33)).text);
assertEquals(" $ 16,789 ", cfDft.apply(16789.2).text);
assertEquals(" $ 16,789 ", cfUS.apply(16789.2).text);
assertEquals(" "+pound+" 16,789 ", cfUK.apply(16789.2).text);
assertEquals(" 16,789 "+euro+" ", cfFR.apply(16789.2).text);
assertEquals(" R 16,789 ", cfSA.apply(Double.valueOf(16789.2)).text);
assertEquals(" USD 16,789 ", cfUSD.apply(Double.valueOf(16789.2)).text);
// For -ve numbers, gets a bit more complicated...
assertEquals("-$ 12 ", cfDft.apply(-12.33).text);
assertEquals(" $ -12 ", cfUS.apply(-12.33).text);
assertEquals("-"+pound+" 12 ", cfUK.apply(-12.33).text);
assertEquals("-12 "+euro+" ", cfFR.apply(-12.33).text);
assertEquals("-R 12 ", cfSA.apply(Double.valueOf(-12.33)).text);
assertEquals(" USD (12)", cfUSD.apply(Double.valueOf(-12.33)).text);
assertEquals("-$ 16,789 ", cfDft.apply(-16789.2).text);
assertEquals(" $ -16,789 ", cfUS.apply(-16789.2).text);
assertEquals("-"+pound+" 16,789 ", cfUK.apply(-16789.2).text);
assertEquals("-16,789 "+euro+" ", cfFR.apply(-16789.2).text);
assertEquals("-R 16,789 ", cfSA.apply(Double.valueOf(-16789.2)).text);
assertEquals(" USD (16,789)", cfUSD.apply(Double.valueOf(-16789.2)).text);
// For zero, should be Space + currency symbol + spaces + Minus + spaces
assertEquals(" $ - ", cfDft.apply((double) 0).text);
assertEquals(" $ - ", cfUS.apply((double) 0).text);

Binary file not shown.