【问题标题】:Validating decimal numbers in a locale-sensitive way in Java [duplicate]在Java中以区域设置敏感的方式验证十进制数[重复]
【发布时间】:2013-01-07 19:55:46
【问题描述】:

可能重复:
Parsing numbers safely and locale-sensitively

如何以区域设置敏感的方式验证包含十进制数字的字符串? NumberFormat.parse 允许太多,而 Double.parseDouble 仅适用于英语语言环境。这是我尝试过的:

public static void main(String[] args) throws ParseException {
    Locale.setDefault(Locale.GERMAN);

    NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.getDefault());
    Number parsed = numberFormat.parse("4,5.6dfhf");
    System.out.println("parsed = " + parsed); // prints 4.5 instead of throwing ParseException

    double v = Double.parseDouble("3,3"); // throws NumberFormatException, although correct
}

【问题讨论】:

  • 如果您的语言环境是德语,并且输入是3.3 而不是3,3,是否应该抛出异常?
  • Number parsed = numberFormat.parse("4.5.6dfhf"); 也可以工作并产生456... Eurgh...
  • jlordo:至少它应该接受正确的数字...
  • assylias:是的,这就是我的意思,它允许太多... :(

标签: java validation


【解决方案1】:

关于

Number parsed = numberFormat.parse("4,5.6dfhf");

问题,您可以使用 NumberFormat.parse(String source, ParsePosition pos) 并检查它停止解析的位置是否确实是字符串的最后一个位置。

另外,关于 4.5.6 的问题,您可以尝试通过 setGroupingUsed(boolean newValue) 设置分组,因为我认为这是由 '.' 产生的问题。字符是语言环境中的分组字符。

应该是这样的

NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.getDefault());
numberFormat.setGroupingUsed(false);
ParsePosition pos;
String nString = "4,5.6dfhf";

Number parsed = numberFormat.parse(nString, pos);
if (pos.getIndex() == nString.length()) // pos is set AFTER the last parsed position
   System.out.println("parsed = " + parsed);
else
   // Wrong

【讨论】:

  • 但这仍然会接受诸如“4.5.6”之类的无意义输入。
  • 实际上 if(nString.length() == pos.getIndex()) 条件(不从长度中减去一个)似乎是正确的条件
  • Andreas_D:我猜点被忽略了,就像英文语言环境忽略逗号一样
  • 如果您发现我的答案有用,将其标记为正确会很酷! =)
  • Manuel Miranda:我想这两个答案都是正确的,但无论如何这似乎更通用,所以我会接受这个:)
【解决方案2】:

根据您上面的评论,您可以使用:

String input = "3,3"; // or whatever you want
boolean isValid = input.matches("^\\d+([.,]\\d+)?$");
double value = Double.parseDouble(input.replaceAll(",", "."));

如果分隔符可以是逗号以外的其他东西,只需将其添加到方括号中:

double value = Double.parseDouble(input.replaceAll("[,]", "."));

【讨论】:

  • 问题是不能保证语言环境是德语。它可以是任何东西。您认为这适用于任何语言环境?
  • 只要分隔符是点或逗号,都可以。我不知道区域设置,其中分隔符是别的东西。
  • 空间怎么样? 1 000 000 可能在某些语言环境中有效。尝试重新开发依赖于语言环境的解析器听起来像是一场危险的游戏……
  • 这取决于您想要的严格程度。如果1 000 000 有效,这个1 00 0000 还是不止一个空格?
  • @jlordo 没错 - 它带来了许多边境案件,而且很难做到正确。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多