From: PJ Fanning Date: Tue, 19 Oct 2021 18:25:33 +0000 (+0000) Subject: [bug-65644] Improved regex for Excel accounting formats. Thanks to Adam DeSapio X-Git-Tag: REL_5_2_0~349 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=77786178ea9e9be63089d4e38b172d085ebf0d2f;p=poi.git [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 --- diff --git a/poi/src/main/java/org/apache/poi/ss/format/CellFormatPart.java b/poi/src/main/java/org/apache/poi/ss/format/CellFormatPart.java index abb9978242..141c98e735 100644 --- a/poi/src/main/java/org/apache/poi/ss/format/CellFormatPart.java +++ b/poi/src/main/java/org/apache/poi/ss/format/CellFormatPart.java @@ -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('-')); } diff --git a/poi/src/test/java/org/apache/poi/ss/format/TestCellFormat.java b/poi/src/test/java/org/apache/poi/ss/format/TestCellFormat.java index 3c0476a9c3..89badeded2 100644 --- a/poi/src/test/java/org/apache/poi/ss/format/TestCellFormat.java +++ b/poi/src/test/java/org/apache/poi/ss/format/TestCellFormat.java @@ -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); diff --git a/poi/src/test/java9/module-info.class b/poi/src/test/java9/module-info.class index 438e778ab5..028b943d0a 100644 Binary files a/poi/src/test/java9/module-info.class and b/poi/src/test/java9/module-info.class differ