Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Unfortunately Double.parseDouble(s) or new BigDecimal(s) seem to be your best options.</p> <p>You cite localisation concerns, but unfortunately there is no way reliably support all locales w/o specification by the user anyway. It is just impossible.</p> <p>Sometimes you can reason about the scheme used by looking at whether commas or periods are used first, if both are used, but this isn't always possible, so why even try? Better to have a system which you know works reliably in certain situations than try to rely on one which may work in more situations but can also give bad results...</p> <p>What does the number 123,456 represent? 123456 or 123.456?</p> <p>Just strip commas, or spaces, or periods, depending on locale specified by user. Default to stripping spaces and commas. If you want to make it stricter, only strip commas OR spaces, not both, and only before the period if there is one. Also should be pretty easy to check manually if they are spaced properly in threes. In fact a custom parser might be easiest here.</p> <p>Here is a bit of a proof of concept. It's a bit (very) messy but I reckon it works, and you get the idea anyways :).</p> <pre><code>public class StrictNumberParser { public double parse(String numberString) throws NumberFormatException { numberString = numberString.trim(); char[] numberChars = numberString.toCharArray(); Character separator = null; int separatorCount = 0; boolean noMoreSeparators = false; for (int index = 1; index &lt; numberChars.length; index++) { char character = numberChars[index]; if (noMoreSeparators || separatorCount &lt; 3) { if (character == '.') { if (separator != null) { throw new NumberFormatException(); } else { noMoreSeparators = true; } } else if (separator == null &amp;&amp; (character == ',' || character == ' ')) { if (noMoreSeparators) { throw new NumberFormatException(); } separator = new Character(character); separatorCount = -1; } else if (!Character.isDigit(character)) { throw new NumberFormatException(); } separatorCount++; } else { if (character == '.') { noMoreSeparators = true; } else if (separator == null) { if (Character.isDigit(character)) { noMoreSeparators = true; } else if (character == ',' || character == ' ') { separator = new Character(character); } else { throw new NumberFormatException(); } } else if (!separator.equals(character)) { throw new NumberFormatException(); } separatorCount = 0; } } if (separator != null) { if (!noMoreSeparators &amp;&amp; separatorCount != 3) { throw new NumberFormatException(); } numberString = numberString.replaceAll(separator.toString(), ""); } return Double.parseDouble(numberString); } public void testParse(String testString) { try { System.out.println("result: " + parse(testString)); } catch (NumberFormatException e) { System.out.println("Couldn't parse number!"); } } public static void main(String[] args) { StrictNumberParser p = new StrictNumberParser(); p.testParse("123 45.6"); p.testParse("123 4567.8"); p.testParse("123 4567"); p.testParse("12 45"); p.testParse("123 456 45"); p.testParse("345.562,346"); p.testParse("123 456,789"); p.testParse("123,456,789"); p.testParse("123 456 789.52"); p.testParse("23,456,789"); p.testParse("3,456,789"); p.testParse("123 456.12"); p.testParse("1234567.8"); } } </code></pre> <p>EDIT: obviously this would need to be extended for recognising scientific notation, but this should be simple enough, especially as you don't have to actually validate anything after the e, you can just let parseDouble fail if it is badly formed.</p> <p>Also might be a good idea to properly extend NumberFormat with this. have a getSeparator() for parsed numbers and a setSeparator for giving desired output format... This sort of takes care of localisation, but again more work would need to be done to support ',' for decimals...</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload