扫描器hasNext()方法和转义字符

时间:2017-01-30 17:32:43

标签: java regex java.util.scanner

我正在尝试确定Scanner中的下一个标记是否包含某个字符串。但是,如果令牌中有\ n或\ r,则hasNext(String)方法无论如何都会返回false。 (我正在使用Eclipse。)

默认分隔符(空格)不会出现此问题。但是如果使用useDelimiter() - 甚至将分隔符设置为“” - 那么hasNext(String)总是返回false。

如果令牌中某处有转义字符且分隔符也已重置,Scanner hasNext(String)方法是否总是返回false?

import java.util.*;

public class ScannerDemo {

    public static void main(String[] args) {

        Scanner scanner = new Scanner("abcdefg\n\rX");
        scanner.useDelimiter("X");

        // Returns false!! Why?
        System.out.println("" + scanner.hasNext(".*c.*"));
        System.out.println(scanner.next());
        System.out.println("-------------------------------");

        scanner.close();

        scanner = new Scanner("abcde\n\rXfg");
        scanner.useDelimiter("X");

        // Returns false!! Why?
        System.out.println("" + scanner.hasNext(".*c.*"));
        System.out.println(scanner.next());
        System.out.println("-------------------------------");

        scanner.close();

        scanner = new Scanner("\n\rabcdeXfg");
        scanner.useDelimiter("X");

        // Returns false!! Why?
        System.out.println("" + scanner.hasNext(".*c.*"));
        System.out.println(scanner.next());
        System.out.println("-------------------------------");

        scanner.close();

        scanner = new Scanner("abcdeXfg\n\r");
        scanner.useDelimiter("X");

        // Returns true, as expected
        System.out.println("" + scanner.hasNext(".*c.*"));
        System.out.println(scanner.next());
        System.out.println("-------------------------------");

        scanner.close();

        scanner = new Scanner("abcdeXfg");
        scanner.useDelimiter("X");

        // Returns true, as expected
        System.out.println("" + scanner.hasNext(".*c.*"));
        System.out.println(scanner.next());
        System.out.println("-------------------------------");

        scanner.close();

    }
}

2 个答案:

答案 0 :(得分:1)

默认情况下,.正则表达式通配符与\r\n不匹配。

您需要指定标记DOTALL,但由于您未直接使用Pattern类,请将(?s)添加到正则表达式中来执行此操作:

scanner.hasNext("(?s).*c.*")

正如DOTALL javadoc所说:

  

在dotall模式下,表达式.匹配任何字符,包括行终止符。默认情况下,此表达式与行终止符不匹配。

Pattern的javadoc中.的说明也涵盖了这一点:

  

.任何字符(可能与line terminators匹配也可能不匹配)

链接说:

  

正则表达式.匹配除行终止符之外的任何字符,除非指定了DOTALL标志。

答案 1 :(得分:0)

您可能需要查看here。其中一个答案解释说:

“如果你手中有一堆带有.next()的手表,你的IDE ......实际上是每个手表的光标位置。” --Amalgovinus

这可能是您遇到的问题。