了解Scanner中的useDelimiter:为什么我会得到空白令牌?

时间:2012-05-26 10:52:33

标签: java parsing

我正在使用扫描仪和分隔符,我遇到了一个我想要了解的奇怪行为。

我正在使用这个程序:

    Scanner sc = new Scanner("Aller à : Navigation, rechercher");
    sc.useDelimiter("\\s+|\\s*\\p{Punct}+\\s*");
    String word="";
    while(sc.hasNext()){
        word = sc.next();
        System.out.println(word);
    }

输出结果为:

Aller
à

Navigation
rechercher

首先,我不明白为什么我得到一个空白令牌,documentation说:

  

根据分隔模式的类型,可能会返回空标记。例如,模式“\ s +”将不返回空标记,因为它匹配分隔符的多个实例。分隔模式“\ s”可以返回空标记,因为它一次只传递一个空格。

我正在使用\\s+,为什么它会返回一个空白标记?

然后我还想了解有关正则表达式的另一件事。如果我使用“反向”正则表达式更改分隔符:

    sc.useDelimiter("\\s*\\p{Punct}+\\s*|\\s+");

输出正确,我得到:

Aller
à
Navigation
rechercher

为什么它会起作用?

编辑:

在这种情况下:

    Scanner sc = new Scanner("(23 ou 24 minutes pour les épisodes avec introduction) (approx.)1");
    sc.useDelimiter("\\s*\\p{Punct}+\\s*|\\s+"); //second regex

introductionapprox之间仍有空白令牌。有可能避免它吗?

2 个答案:

答案 0 :(得分:1)

我感觉你在有空格后跟标点符号的地方造成两个分隔符捕获。为什么不简单地使用[\\s\\p{Punct}]+

此正则表达式\\s+|\\p{Punct}+将首先捕获空白区域并吞下它,然后将下一个分隔符捕获为标点符号。这将是两个彼此相邻的分隔符,两者之间没有任何内容(空令牌)。

答案 1 :(得分:0)

我碰巧遇到了Scanner类的空令牌问题。我认为分隔符模式必须通过用括号括起并将 + 附加到组中来使贪心。我使用的模式看起来像这样

"((\\s)+|(\\\\r\\\\n)+|\\p{Punct}+)+".