Java 匹配一个可能是或不可能是双精度的负数

Java 匹配一个可能是或不可能是双精度的负数,java,regex,Java,Regex,我正在用Java构建一个温度转换器。用户将在JTextField中输入一个数字,使用JComboBox选择起始标签,并使用按钮组中的JRadioButton选择结束标签。用户输入的数字可能具有不同的可能性。可能是 单个整数,例如5 倍数整数,如55 双打,如5.5 上述任何内容的负面版本,如-5、-55或-5.5 JTextField有一个方法getText(),它返回字符串的值。然后将其转换为双精度,最后转换为所需的结束标签。由于字符串必须转换为双精度,因此JTextField中不允许使用

我正在用Java构建一个温度转换器。用户将在
JTextField
中输入一个数字,使用
JComboBox
选择起始标签,并使用
按钮组中的
JRadioButton
选择结束标签。用户输入的数字可能具有不同的可能性。可能是

  • 单个整数,例如5
  • 倍数整数,如55
  • 双打,如5.5
  • 上述任何内容的负面版本,如-5-55-5.5
JTextField
有一个方法
getText()
,它返回字符串的值。然后将其转换为双精度,最后转换为所需的结束标签。由于字符串必须转换为双精度,因此
JTextField
中不允许使用字母字符。所以我用正则表达式来解决这个问题。我现在有

String tempV = startTempValInput.getText();
if (tempV.matches("-?[0-9]+\\.[0-9]+")) {
   // Code Here
}
但是,它不能识别单个或多个整数。如何修改它以包含整数

tempV.matches("-?[0-9]+(\\.[0-9]+)?")
细分:

  • -?
    -这将匹配负数0或1次
  • [0-9]+
    -这将匹配数字字符1次或多次
  • (\\.[0-9]+)?
    -这将匹配可能的小数点到无穷大
    • \\.
      -这将匹配一个句点。需要双转义,因为Java将正则表达式识别为普通字符串。这意味着您必须避开反斜杠
    • [0-9]+
      -这将匹配数字字符1次或多次
    • 这都用
      ()?
      包装,因为小数点是可选的。如果您尝试使用
      -?[0-9]+\.?[0-9]+
      ,它将无法识别单个整数。它会将负数和句点视为可选,但由于
      +
      返回1或更多,因此至少需要两个整数
另一种选择是

tempV.matches("-?([0-9]+\\.)?[0-9]+")
因为字符串必须转换为双精度,所以JTextField中不允许使用字母字符

2.0E3

我只需要使用
Double.parseDouble
,并捕获
NumberFormatException

try {
    Double.parseDouble(inStr);
} catch (NumberFormatException e) {
    // string doesn't represent a double
}

你可以自己用正则表达式来做,但是有各种各样的边缘情况需要考虑:科学记数法(如上所示)、领先的
+
,等等。这当然是可以管理的,但是为什么要编写代码来完成已经为你做过的事情呢?

你可以用这一点来覆盖所有的基础:
编辑-确保某个地方有数字,谢谢@yshavit

^(?=\D*\D)(?=[\D.-]+$)-?\D*\.?\D*$

还可以扩展到更多内容:
已修改-简化版,不需要某些断言

 # (?i)^(?=[^e]*\d)[+-]?\d*\.?\d*(?:e[+-]?\d+)?$
 # "(?i)^(?=[^e]*\\d)[+-]?\\d*\\.?\\d*(?:e[+-]?\\d+)?$"


 (?i)                   # Case insensitive modifier
 ^                      # Beginning of string
 (?= [^e]* \d )         # Lookahead must be a digit (and before exponent)
 [+-]? \d* \.? \d*      # Consume correct numeric form 
 (?: e [+-]? \d+ )?     # Consume correct exponent form
 $                      # End of string

捕获大范围双输入的模式是:

^(?![+-]$|[-+]E|E|$|\.$)[+-]?\d*(\.?\d*)?(E-?\d+)?$
与以下情况的边缘情况相匹配:

1
1.
.1
4E7
3.4E-5
+7.4
-5
见a

因为每一项都是可选的,所以需要进行消极的前瞻,以捕获本来匹配的退化情况


请注意,此正则表达式不能防止过流/欠流,例如
1E9999
,它太大,无法用double表示。

用户是否可以问:“什么是
.5
度C?”@sln是,如果您只是计划验证一个不会在字符串上反弹的字符串,则必须将其作为
0.5
度数进行询问,以使
.5
方法是允许且有效的。如果有兴趣,我发布了一个正则表达式,它应该验证所有这些数字字符串表示形式。
是一个有效的数字吗?前导+是什么?一个正数。这是多余的,但是被
parseDouble
允许。你的建议是有效的。然而,我正在探索正则表达式和java。它更像是一个测试项目,而不是一个严肃的应用程序。我可能最终会改用这种方法。如果是这样的话,以后请在原始帖子中包含这类信息。我把这个问题理解为试图务实地找出一个字符串是否可以被解析为double;我没有意识到这是一个正则表达式练习。请注意,这确实遗漏了一些
Double.parseDouble
允许的数字:
+2
1e2
.1
…请注意,这是有史以来最糟糕的模式,因为在输入整数时,它需要找到所有数字,然后才能使用点失败。不确定,
-.
+E2
是否为有效数字?