如何使用扫描仪扫描浮点值?

时间:2015-08-28 19:07:11

标签: java regex java.util.scanner

好的,所以我使用扫描仪识别字符串中的下一个标记是浮点值还是十进制值,如果不是,它将逐字符扫描,直到找到小数或浮点数。

因此,如果输入类似12/35.6+=123.5.6,则应按此顺序找到令牌。

  
      
  1. ' 12'
  2.   
  3. ' /'
  4.   
  5. ' 35.6'
  6.   
  7. ' +'
  8.   
  9. ' ='
  10.   
  11. ' 123.5'
  12.   
  13. ' 0.6' (解释为0.6浮动)
  14.   

这是我到目前为止所拥有的。

Scanner interpreter = new Scanner(input);

    //Allows scanning of individual char tokens
    interpreter.useDelimiter("");

    Pattern integerPattern = Pattern.compile("\\d*(\\.\\d+)?");

    //read through input
    while (interpreter.hasNext()) {

        //determines if next token is a float/decimal
        if (interpreter.hasNext(integerPattern)) {
            //extract number token
            String strVal = interpreter.findInLine(integerPattern);
            float value = Float.parseFloat(strVal);
            tokenList.add(new Token(11, value));

        }
        else{
            //should mean the next token is not a decimal or float
            //scan over token char by char
        }
     }

我遇到的问题是当我输入类似123.4.5的内容时,它应该捕获第一个令牌123.4处理它,然后捕获.5作为下一个令牌。但是,它现在正好赶上123.4但是当它处理下一个令牌if (interpreter.hasNext(integerPattern))时返回false,将句点作为单个字符读取。

代币看起来像这样

  
      
  1. ' 123.4'
  2.   
  3. ''
  4.   
  5. ' 5'
  6.   

3 个答案:

答案 0 :(得分:1)

这将扫描下一个浮点数。

Scanner interpreter = new Scanner(input);
while(interpreter.hasNextFloat()){
    tokenList.add(newToken(11, scanner.nextFloat()));
}

答案 1 :(得分:1)

这是正在发生的事情。

当您使用hasNext(Pattern)方法时,扫描程序会查看其完整下一个标记,并确定该完整标记是否与该模式匹配。

当分隔符为空时,表示完整的下一个标记是单个字符。如果您尝试将String.split()用于空模式,则可以看到。

因此,当您输入123.4.5时,hasNext()实际看到的只是1。幸运的是,这符合你的模式,所以你进入if的主体。

此时,您正在使用findInLine(pattern)。此方法忽略分隔符和标记,而只是查找匹配模式。所以它会看到整个123.4并将其交给你。

现在您已离开.5,下一个完整令牌就是 . !这与模式不匹配(您的模式表明,如果有.,则必须至少跟一个数字。单个点不匹配)。因此,hasNext(integerPattern)失败,您将进入else部分。

以下是一种可能的解决方案:hasNextfindInLine具有不同的模式:

    Pattern findPattern = Pattern.compile("\\d*(\\.\\d+)?");
    Pattern tokenPattern = Pattern.compile("\\d|\\.(?=\\d)");

tokenPattern具有正向前瞻,这意味着它将接受单字符令牌:

  • 数字
  • 一个圆点 - 前提是它后面有数字,但它们不在匹配中。

如果您有一个符合这些条件的字符,您就知道您能够匹配完整模式。所以你的程序改为:

while (interpreter.hasNext()) {

    // Do we have the beginning of a number?
    if (interpreter.hasNext(tokenPattern)) {
        // Extract the full number
        String strVal = interpreter.findInLine(findPattern);
        float value = Float.parseFloat(strVal);
        tokenList.add(new Token(11, value));

    }
    else{
        // Handle single char token
    }
 }

答案 2 :(得分:0)

您的问题明确有两种模式

首先:例如1.011.89

处理方式:

\d+(?:\.\d+)?

第二:例如.987.11

处理方式:

\.\d+

然后你只需使用或(|)将它们全部放入一个正则表达式

\.\d+|\d+(?:\.\d+)?

请参阅:DEMO

这里的一个技巧是我只想在上面的表达式中使用模式\.\d+而不是\d+(?:\.\d+)?,这对你的工作很重要。

相关问题