Java 带有正则表达式的扫描仪未读取整个文件

Java 带有正则表达式的扫描仪未读取整个文件,java,regex,java.util.scanner,Java,Regex,Java.util.scanner,这是我的解析方法 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.nex

这是我的解析方法

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!");
    }
  }
它仅与以下词语匹配:

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

不知怎的,scanner认为它已经到达了文件的末尾,但这不是真的。你知道为什么会这样吗?我检查了我的正则表达式,它看起来确实有效(一个单词包含字母A-z和撇号)。谢谢

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

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

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

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

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

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

扫描仪的hasNext基本上是无用的

扫描仪的工作原理如下:

  • 任何相关的时间(在任何
    next()
    /
    nextX()
    调用上,或任何
    hasNext
    调用上,但不在
    nextLine()上)
    ,确保扫描程序知道“队列中的下一个令牌”。如果还没有令牌,则从提要中读取另一个令牌。这是通过完全不考虑请求的内容,而是扫描流的任意一端或“分隔符”(默认情况下为“任何空白”)来完成的.到那时为止的一切都是下一个标志
  • hasX()检查下一行的标记,并根据其是否匹配返回true或false。它与是否还有任何数据需要读取无关
  • nextLine忽略了所有这一切,并且不能很好地与scanner中的其他任何东西一起工作
  • 因此,您正在调用hasNext,hasNext正在忠实地报告:行中的下一个令牌是
    银行,
    ,它与regexp不匹配,因此返回
    false
    。正如文档所说

    解决方案 忘记hasX,你不需要它们。你也永远不需要nextLine。如果分隔符不好,如果你更改分隔符,Scanner工作得最好(即永远不要调用nextLine,调用
    useDelimiter(“\r?\n”)
    next()
    ),然后调用.nextX()方法。这就是你所做的一切


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

    扫描仪的hasNext基本上是无用的

    扫描仪的工作原理如下:

  • 任何相关的时间(在任何
    next()
    /
    nextX()
    调用上,或任何
    hasNext
    调用上,但不在
    nextLine()上)
    ,确保扫描程序知道“队列中的下一个令牌”。如果还没有令牌,则从提要中读取另一个令牌。这是通过完全不考虑请求的内容,而是扫描流的任意一端或“分隔符”(默认情况下为“任何空白”)来完成的.到那时为止的一切都是下一个标志
  • hasX()检查下一行的标记,并根据其是否匹配返回true或false。它与是否还有任何数据需要读取无关
  • nextLine忽略了所有这一切,并且不能很好地与scanner中的其他任何东西一起工作
  • 因此,您正在调用hasNext,hasNext正在忠实地报告:行中的下一个令牌是
    银行,
    ,它与regexp不匹配,因此返回
    false
    。正如文档所说

    解决方案 忘记hasX,你不需要它们。你也永远不需要nextLine。如果分隔符不好,如果你更改分隔符,Scanner工作得最好(即永远不要调用nextLine,调用
    useDelimiter(“\r?\n”)
    next()
    ),然后调用.nextX()方法。这就是你所做的一切


    因此,只需调用
    next()
    ,检查它是否匹配,然后继续操作。

    请注意,解析器未解析的第一个单词
    bank
    ,也是文本的第一个单词,后面跟的字符不是字母或空格(在本例中是逗号)请注意,解析器未解析的第一个单词,
    bank
    ,也是文本的第一个单词,后面跟的字符不是字母或空格(在本例中是逗号)