【问题标题】:Java: how to parse double from regexJava:如何从正则表达式解析双精度
【发布时间】:2010-09-09 23:14:12
【问题描述】:

我有一个看起来像“A=1.23;B=2.345;C=3.567”的字符串

我只对“C=3.567”感兴趣

我目前拥有的是:

     Matcher m = Pattern.compile("C=\\d+.\\d+").matcher("A=1.23;B=2.345;C=3.567");

    while(m.find()){ 
        double d = Double.parseDouble(m.group());
        System.out.println(d);
    }

问题是它显示 3 与 567 是分开的

输出:

3.0

567.0

我想知道如何包含小数,以便输出“3.567”

编辑:如果 C 没有小数点,我也想匹配它: 所以我想捕获 3567 和 3.567

由于 C= 也内置在模式中,我如何在解析双精度之前将其删除?

【问题讨论】:

  • 句点 (".") 不是数字。

标签: java regex


【解决方案1】:

这部分我可能弄错了,但将两者分开的原因是group() 只会匹配最后匹配的子序列,即每次调用find() 时匹配的任何内容。罢工> 谢谢,马克拜尔斯。

当然,您可以通过将所需的整个部分放入“捕获组”中来解决此问题,这是通过将其放在括号中来完成的。这使得您可以将正则表达式的匹配部分组合到一个子字符串中。您的模式将如下所示:

Pattern.compile("C=(\\d+\\.\\d+)")

对于解析 3567 或 3.567,您的模式将是 C=(\\d+(\\.\\d+)?) 第 1 组代表整数。另外,请注意,由于您特别想匹配句点,因此您希望转义 .(句点)字符,以便它不会被解释为“任何字符”标记。不过,对于这个输入,这并不重要

然后,要获得 3.567,您会调用 m.group(1) 来获取第一个(从 1 开始计数)指定组。这意味着您的 Double.parseDouble 调用本质上将变为 Double.parseDouble("3.567")

至于把 C= 从你的模式中去掉,因为我对 RegExp 不是很精通,我可能会建议你 split 你的输入字符串在分号上,然后检查每个splits 包含 C;然后你可以应用模式(使用捕获组)从你的 Matcher 中获取 3.567。

编辑对于 gawi 评论中更一般(并且可能更有用!)的案例,请使用以下内容(来自http://www.regular-expressions.info/floatingpoint.html

Pattern.compile("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?")

这支持可选的符号,可选的整数或可选的小数部分,以及可选的正/负指数。在需要单独挑选零件的地方插入捕获组。指数作为一个整体在其自己的组中,使其作为一个整体成为可选的。

【讨论】:

  • 注意:正则表达式不处理以下浮点数:10 10. .1 1.3e10 1.2e-12 1.41e+12
  • @gawi 谢谢 :) 我已经用正则表达式更新了答案,应该可以解决问题。 10. 是否视为有效浮点数,有小数点但后面没有数字?
  • 10.在 Java 中是一个有效的浮点字面量(嗯……准确地说是 10.f)
  • 我不明白您为什么认为使用group() 与问题有关。他的正则表达式中没有任何额外的组。
  • @Mark Byers 我想这表明我应该先尝试他的代码,然后再响应和误读 javadocs。我刚刚运行了 OP 的代码,但并没有产生与提到的相同的结果(获得两个单独的匹配项)。感谢您的帮助:)
【解决方案2】:

您的正则表达式只匹配数字字符。你还需要匹配小数点:

Pattern.compile("\\d+\\.\\d+")

. 被转义,因为这将匹配任何未转义的字符。

注意:这将只匹配带有小数点的数字,这就是您在示例中所拥有的。

【讨论】:

    【解决方案3】:

    要匹配任何数字和点的序列,您可以将正则表达式更改为:

    "(?<=C=)[.\\d]+"
    

    如果你想确定只有一个点,你可能想尝试这样的事情:

    "(?<=C=)\\d+(?:\\.\\d+)?"
    

    您还应该知道,此模式可以匹配ABC=1.2.3; 中的1.2。您应该考虑是否需要改进正则表达式以正确处理这种情况。

    【讨论】:

      【解决方案4】:

      如果您需要用点、逗号、正数和负数验证小数:

      Object testObject = "-1.5";
      boolean isDecimal = Pattern.matches("^[\\+\\-]{0,1}[0-9]+[\\.\\,][0-9]+$", (CharSequence) testObject);
      

      祝你好运。

      【讨论】:

      • {1} 不是隐含的吗?
      • @cutter 是的,我不记得我为什么添加那个 {1}。也许更清楚,或者因为我在 2015 xD 中对正则表达式非常陌生
      • 唯一能正确处理负数(和正数+前导)的答案。
      【解决方案5】:

      如果您想要一个输入的正则表达式,它可能是双精度或只是整数而没有任何 *.0 的东西,您可以使用这个:
      Pattern.compile("(-?\d+\.?\d*)")

      【讨论】:

        猜你喜欢
        • 2018-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多