while (!scannerObject.hasNext(patternObject)) 仅适用于一次迭代

while (!scannerObject.hasNext(patternObject)) works for only one iteration

问题

我只从一个由 hasNext(Pattern pattern) 条件控制的 while 循环中获得了一次成功的迭代。我尝试使用 .next() 'clear' 输入流 (?) 但没有成功。

行为

如果我第一次输入无效,看似有效的后续输入将继续执行 System.out.print("You did not enter a valid size. Try again: ") 行。但是这一行应该只在 Scanner getPizzaSize 没有有效输入时执行。

如果我第一次输入有效输入,它会工作并且程序会前进,但是当 while (orderingPizza) 出现第二次迭代时,getPizzaSize 的所有输入(有效与否)执行 System.out.print("You did not enter a valid size. Try again: ")行。

我只从我的 !getPizzaSize.hasNext(validPizzaSizes) 循环中获得了一次成功的迭代:

Please place the order for your pizza.
Size (s = small, l = large, f = family): s
Please place the order for your pizza.
Size (s = small, l = large, f = family): s
You did not enter a valid size. Try again: 

我应该得到:

Please place the order for your pizza.
Size (s = small, l = large, f = family): s
Please place the order for your pizza.
Size (s = small, l = large, f = family): s
Please place the order for your pizza.
Size (s = small, l = large, f = family):

(我使用的正则表达式应该匹配:s, S, l, L, f, F。这个link可能是为了测试结果:https ://regexr.com/5gdla.)

一个解决方案

如果我在 .hasNext(Pattern pattern) 循环中重新声明 Scanner getPizzaSize,循环将按预期运行:

  1. 无效输入后跟You did not enter valid input . . . try again;和
  2. 有效的输入通过程序前进

我想明白什么

我从 getPizzaSize.next() 读取的方式似乎有问题。但我不知道问题是什么。这是我的正则表达式吗?关于 .next().hasNext(Pattern pattern) 结合的性质?对于整数输入,.hasNextInt().next() 工作得很好。

import java.util.Scanner;
import java.util.regex.Pattern;

public class PizzaOrder{

    public static void main(String[] args) {
        // Initialise Scanner object.
        Scanner getPizzaSize = new Scanner(System.in);

        // Initialise Pattern object for detecting valid size input.
        Pattern validPizzaSizes = Pattern.compile("^[slf]$", Pattern.CASE_INSENSITIVE);

        while (true) {
            // Ask for pizza size.
            System.out.print("Please place the order for your pizza.\n" +
                    "Size (s = small, l = large, f = family): ");
            // Validate size input.
            while (!getPizzaSize.hasNext(validPizzaSizes)) {
                System.out.print("You did not enter a valid size. Try again: ");
                getPizzaSize.next();
            }
            // Set pizza size.
            String pizzaSize = getPizzaSize.next();
        }
    }
}
            

您的正则表达式表示“s”、“l”或“f”必须是字符串的开头和结尾,如 ^$ 锚点所示。但是,就扫描器而言,您输入的第二个 s 不在字符串的开头。在您输入的第一个 s 之后 (可能还用换行符分隔)!

您不应使用 ^ 锚点。您的正则表达式应该只是:

[slf]$

这也解释了为什么创建新的扫描仪有效。因为新的扫描仪不知道您之前输入的s