diff --git a/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java b/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java index cbef22d91c0..c4aaa28193a 100644 --- a/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java +++ b/make/jdk/src/classes/build/tools/cldrconverter/Bundle.java @@ -79,6 +79,7 @@ class Bundle { "NumberElements/nan", "NumberElements/currencyDecimal", "NumberElements/currencyGroup", + "NumberElements/lenientMinusSigns", }; private static final String[] TIME_PATTERN_KEYS = { diff --git a/make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java b/make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java index 6d5dde0d181..98c0605f8b7 100644 --- a/make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java +++ b/make/jdk/src/classes/build/tools/cldrconverter/LDMLParseHandler.java @@ -844,6 +844,26 @@ class LDMLParseHandler extends AbstractLDMLHandler { }); break; + // Lenient parsing + case "parseLenients": + if ("lenient".equals(attributes.getValue("level"))) { + pushKeyContainer(qName, attributes, attributes.getValue("scope")); + } else { + pushIgnoredContainer(qName); + } + break; + + case "parseLenient": + // Use only the lenient minus sign for now + if (currentContainer instanceof KeyContainer kc + && kc.getKey().equals("number") + && attributes.getValue("sample").equals("-")) { + pushStringEntry(qName, attributes, currentNumberingSystem + "NumberElements/lenientMinusSigns"); + } else { + pushIgnoredContainer(qName); + } + break; + default: // treat anything else as a container pushContainer(qName, attributes); @@ -1150,6 +1170,14 @@ class LDMLParseHandler extends AbstractLDMLHandler { currentStyle = ""; putIfEntry(); break; + case "parseLenient": + if (currentContainer instanceof StringEntry se) { + // Convert to a simple concatenation of lenient minuses + // e.g. "[\--﹣ ‐‑ ‒ – −⁻₋ ➖]" -> "--﹣‐‑‒–−⁻₋➖" for the root locale + put(se.getKey(), se.getValue().replaceAll("[\\[\\]\\\\ ]", "")); + } + break; + default: putIfEntry(); } diff --git a/src/java.base/share/classes/java/text/CompactNumberFormat.java b/src/java.base/share/classes/java/text/CompactNumberFormat.java index fae11cbdba1..7163b2dd63b 100644 --- a/src/java.base/share/classes/java/text/CompactNumberFormat.java +++ b/src/java.base/share/classes/java/text/CompactNumberFormat.java @@ -147,7 +147,7 @@ import java.util.stream.Collectors; * a compact pattern. This special pattern can appear explicitly for any specific * range, or considered as a default pattern for an empty string. * - *

Negative Subpatterns

+ *

Negative Subpatterns

* A compact pattern contains a positive and negative subpattern * separated by a subpattern boundary character {@code ';'}, * for example, {@code "0K;-0K"}. Each subpattern has a prefix, @@ -159,7 +159,10 @@ import java.util.stream.Collectors; * the negative prefix and suffix. The number of minimum integer digits, * and other characteristics are all the same as the positive pattern. * That means that {@code "0K;-00K"} produces precisely the same behavior - * as {@code "0K;-0K"}. + * as {@code "0K;-0K"}. In {@link NumberFormat##leniency lenient parsing} + * mode, loose matching of the minus sign pattern is enabled, following the + * LDML’s + * loose matching specification. * *

Escaping Special Characters

* Many characters in a compact pattern are taken literally, they are matched @@ -1585,6 +1588,9 @@ public final class CompactNumberFormat extends NumberFormat { * and are not digits that occur within the numerical portion * *

+ * When lenient, the minus sign in the {@link ##negative_subpatterns + * negative subpatterns} is loosely matched against lenient minus sign characters. + *

* The subclass returned depends on the value of * {@link #isParseBigDecimal}. *

*

+ * When lenient, the minus sign in the {@link ##negative_subpatterns + * negative subpatterns} is loosely matched against lenient minus sign characters. + *

* The subclass returned depends on the value of {@link #isParseBigDecimal} * as well as on the string being parsed. *