【问题标题】:Understanding useDelimiter in Scanner : why I get blank token?了解 Scanner 中的 useDelimiter:为什么我得到空白令牌?
【发布时间】:2012-05-26 10:52:33
【问题描述】:

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

我正在使用这个程序:

    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 之间还有一个空白标记。可以避免吗?

【问题讨论】:

  • 我感觉您在有空格后跟标点符号的地方导致两次分隔符捕获。为什么不简单地使用"[\\s\\p{Punct}]+"?还是我过度简化了问题?
  • @HovercraftFullOfEels 感谢您的正则表达式非常适合我的需求!我以为\\s+|\\p{Punct}+(我从这个开始,没有提到)和你的一样,但这不是为什么?
  • 我还在寻找\\s*\\p{Punct}+\\s*|\\s+\\s+|\\s*\\p{Punct}+\\s*之间区别的解释

标签: java parsing


【解决方案1】:

我有一种感觉,您在有空格后跟标点符号的地方导致两次分隔符捕获。为什么不简单地使用[\\s\\p{Punct}]+

这个正则表达式\\s+|\\p{Punct}+ 将首先捕获空白并将其吞下,然后将捕获下一个分隔符作为标点符号。这将是两个相邻的分隔符,中间没有任何内容(空标记)。

【讨论】:

  • 非常感谢,所以在我的示例中,如果第二种模式有效,那是因为\\s*\\p{Punct}+\\s* 已经捕获` : ` 那么\\s+ 没有被使用并且没有空白。我说的对吗?
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 2016-03-03
    • 1970-01-01
    相关资源
    最近更新 更多