【问题标题】:Scanner with Regex not reading the entire file带有正则表达式的扫描仪未读取整个文件
【发布时间】:2020-12-14 11:48:10
【问题描述】:

这是我的解析方法。

public void loadInput(File fileName) throws IOException {
    try {
      Scanner s = new Scanner(fileName);
      int numWords = 0;
      while (s.hasNext("(?<!')[\\w']+")) {
        System.out.println("word:" + s.next());
        numWords++;
      }
      System.out.println("Number of words: " + numWords);
    } catch (IOException e) {
      System.out.println("Error accessing input file!");
    }
  }

这是一个示例输入文件:

Alice was beginning to get very tired of sitting by her sister
on the bank, and of having nothing to do:  once or twice she had
peeped into the book her sister was reading, but it had no
pictures or conversations in it, `and what is the use of a book,'
thought Alice `without pictures or conversation?'

  So she was considering in her own mind (as well as she could,
for the hot day made her feel very sleepy and stupid), whether
the pleasure of making a daisy-chain would be worth the trouble
of getting up and picking the daisies, when suddenly a White
Rabbit with pink eyes ran close by her.

它只匹配这些词:

word:Alice
word:was
word:beginning
word:to
word:get
word:very
word:tired
word:of
word:sitting
word:by
word:her
word:sister
word:on
word:the
Number of words: 14

不知何故,扫描仪认为它已到达文件末尾,这是不正确的。关于为什么会发生这种情况的任何想法?我检查了我的正则表达式,它似乎确实有效(一个单词包含字母 a-z 和撇号)。谢谢!

【问题讨论】:

  • 请注意,您的解析器未解析的第一个单词 bank 也是文本的第一个单词,其后跟一个不是字母或空格的字符(在这种情况下是逗号)

标签: java regex java.util.scanner


【解决方案1】:

扫描仪将文本分成“标记”。默认的标记分隔符是空格。当您的程序停止时,当前标记为 bank, 当您将其与 .hasNext() 正则表达式进行比较时,由于末尾有多余的逗号,它不匹配。

解决方案可能是让扫描仪对 .hasNext() 和 .next() 方法都使用空格标记分隔符,并在 println 语句上应用正则表达式。

while(s.hasNext()) {
   Matcher m = wordPattern.matcher(s.next());
   if (m.find()) {
       System.out.println("word:" + m.group(0))
   }
}

【讨论】:

    【解决方案2】:

    scanner 的 hasNext 基本没用。

    扫描仪的工作原理如下:

    1. 相关的任何时间(无论是在任何next() / nextX() 呼叫,或任何hasNext 呼叫,但不是nextLine(),确保扫描器知道“队列中的下一个令牌”。如果有'还没有,然后从提要中读取另一个令牌。这是通过完全忽略所要求的内容来完成的,而是扫描流的结尾,“分隔符”(默认情况下,它是“任何空白”)。到那时为止的所有内容都是下一个标记。
    2. hasX() 检查下一个标记并根据它是否匹配返回真或假。与是否还有数据要读取无关。
    3. nextLine 会忽略所有这些,并且无法与扫描仪中的其他任何内容一起正常工作。

    所以,您调用 hasNext,hasNext 忠实地报告:嗯,行中的下一个标记是 bank,,它与正则表达式不匹配,因此返回 false。正如文档所说。

    解决方案

    忘记 hasX,你不想要那些。你也永远不需要 nextLine。如果分隔符不好(即永远不要调用 nextLine,而是调用 useDelimiter("\r?\n")next())并调用 .nextX() 方法,则扫描仪效果最好。这就是你用它所做的一切。

    所以,只需调用next(),检查它是否匹配,然后继续。

    【讨论】:

      猜你喜欢
      • 2015-06-26
      • 2017-06-18
      • 1970-01-01
      • 2014-10-31
      • 1970-01-01
      • 2020-11-13
      • 1970-01-01
      • 1970-01-01
      • 2018-03-18
      相关资源
      最近更新 更多