当前位置: 首页 > 知识库问答 >
问题:

Java扫描程序-忽略后续字母

危烨煜
2023-03-14

我的程序需要接受整数、单个字符或一个特定字符串(本例中我将使用“pear”)。虽然每一个都可以用空格分隔,但不需要这样做。

目前,我的解析代码依赖于扫描仪,如下所示:

Scanner scanner = new Scanner(System.in);

while (scanner.hasNext()) {
    if (scanner.hasNext("\\s+")) {
        // Ignore whitespace…

    } else if (scanner.hasNext("[-]?\\d+")) {
        // Get a number
        String nextNumberString = scanner.next("[-]?\\d+");
        // Process the string representing the number…

    } else if (scanner.hasNext("pear")) {
        scanner.next("pear");
        // Do something special…

    } else {
        // Get the next character
        Pattern oldDelimiter = scanner.delimiter();
        scanner.useDelimiter("");
        String nextCharAsString = scanner.next();
        scanner.useDelimiter(oldDelimiter);

        char nextCharacter = nextCharAsString.charAt(0);

        if (Character.isWhitespace(nextCharacter)) {
            // Ignore whitespace…
        } else {
            // Process character…
        }

    }
}

目前,我的程序将接受输入像123 d 456 r pear没有任何问题。然而,它也应该接受相同的输入,没有任何空白(123d456rpear),并以相同的方式解释它,并且在我当前的代码中,单个数字被错误地解释为字符。

我觉得原因可能是我使用的正则表达式。但是,添加* 的结尾将导致解析所有后续字符,以及我尝试解析的输入。例如,[-]?\d*将尝试将整个123d456rpear解析为一个数字,而我真正想要的是123,剩下的将在以后解析。我还尝试将所需输入包装到一个组中,然后附加{1},它们也没有起作用。

我还尝试了scanner.findInLine(),但是在我的测试中,这似乎也不起作用。例如,当我尝试这样做时,pear将导致无限循环,尽管我试图跳过pear的第一个实例。

我还尝试将分隔符设置为,就像我在提取单个字符时所做的那样(在这种情况下,它可以按预期工作)。但是,这会导致单独处理每个数字,解析123,而不是123pear也被解释为单个字符。

那么,有人能帮我找出哪里出了问题吗?这个问题与我的正则表达式有关吗?我是不是用错了方法?或者我误解了Scanner类是如何工作的?


共有2个答案

子车睿
2023-03-14

嗯,单个数字被错误地解释为字符,因为扫描器的hasNext方法从默认为空白的定界符给定的符号中提取标记

来自java文档

扫描器使用定界符模式将其输入拆分为标记,默认情况下,定界符模式匹配空白。然后,可以使用各种后续方法将生成的令牌转换为不同类型的值

因此,整个123d456rpear被提取出来,它不是一个数字,而是一个字符串

商勇
2023-03-14

据我所知,Scanner类的思想是提取标记并丢弃分隔符。但除了空格,你不想扔掉任何东西。但是,输入中不需要空格。下面是一个使用外部和内部扫描仪的实现思想。外部标记在空白处(如果有)。内部使用findInLine()。

findInLine

尝试查找由指定字符串构造的模式的下一个匹配项,忽略分隔符。

public void scan(Scanner scanner) {
    while (scanner.hasNext()) {
        String next = scanner.next();
        System.out.println("opening inner scanner: " + next);
        Scanner innerScanner = new Scanner(next);
        do {
            next = innerScanner.findInLine("([-]?\\d+)|(pear)|([a-zA-Z])");
            if (next == null) {
                // Nothing useful in there
            } else if (next.equals("pear")) {
                System.out.println("pear");
            } else if (next.matches("[a-zA-Z]")) {
                System.out.println("char: " + next);
            } else {
                System.out.println("number: " + next);
            }
        } while (next != null);
        innerScanner.close();
    }
}

public void run() {
    scan(new Scanner("123 d 456 pear"));
    scan(new Scanner("123d456pear"));
}

run()方法的输出如下:

opening inner scanner: 123
number: 123
opening inner scanner: d
char: d
opening inner scanner: 456
number: 456
opening inner scanner: pear
pear
opening inner scanner: 123d456pear
number: 123
char: d
number: 456
pear

 类似资料:
  • 我试图让扫描仪在每个@符号上拆分一个字符串,除非转义时(或在一行的开头) 我的RegEx: 从,我的理解,这应该对我的意图有效。 然而,当在扫描仪中使用此模式时,它只是忽略了这样一个事实,即不应将非捕获组计算到分隔符中,只是为了与之匹配,分隔符(要删除/拆分的部分)应仅为“@”。因此,对于以下示例String:“Hello@World“,结果必须是[”Hello“,”World“]。 除了运行以下

  • 我有以下3种方法: > 方法:获取文本并将其单词拆分为特定字符串,然后将其放入字符串数组中。 方法:计算数组中仅由大小写字母组成的字符串的数量。 现在问题来了,如果我调用第三个方法首先通过生成一个文本。 但不知怎么的,代码只是跳过了行text=input.nextLine();并抛出异常(MSG)字符串为空。执行文本“Enter a text:”,后面直接跟着异常。但我无法输入任何文本。 如果我将

  • 我使用AWS托管API网关和DynamoDB直接集成。 我现在正在尝试为我的应用程序添加分页功能,我很难100%实现它。我面临的问题是当我向后扫描时,我会给你一个例子来更好地理解这个问题。 想象一下,我有一个包含20个项目的列表,页面大小为5。 当我查询我的表时,第一个查询将返回。预期的行为 当我查询表时,将第五个元素中的lastEvaluatedKey传递给它,它返回。预期行为。 现在,当我使用

  • 问题内容: 我刚刚了解了Java的Scanner类,现在我想知道它如何与StringTokenizer和String.Split进行比较/竞争。我知道StringTokenizer和String.Split仅适用于字符串,那么为什么要对字符串使用扫描器?扫描仪是否仅打算一站式进行拆分? 问题答案: 他们本质上是课程的马。 设计用于需要解析字符串,提取不同类型数据的情况。它非常灵活,但是可以说它并没

  • 问题内容: 对于Java练习,我试图创建一个程序,该程序从键盘读取整数,直到输入负数为止。 并打印整数的最大值和最小值,而忽略负数。 一旦运行,是否可以在同一程序中进行连续输入?我必须每次都继续运行该程序以输入数字。 任何帮助,将不胜感激 这是我的代码的一部分-它可以工作,但是我认为有一种更简单的方法可以执行我想要的操作,但不确定如何操作! 问题答案: