Java 如果我调用scanner.hasNext,然后调用scanner.next,是否扫描两次

Java 如果我调用scanner.hasNext,然后调用scanner.next,是否扫描两次,java,parsing,tokenize,lexer,Java,Parsing,Tokenize,Lexer,如果调用scanner.hasNext(pattern),然后调用scanner.next(pattern)在java.util.scanner 假设我有很多案例的代码(尝试制作lexer): import java.util.*; 导入java.util.regex.Pattern; 公共类主类{ 公共静态void main(字符串[]args){ 扫描仪=新扫描仪(“你好,世界!3+3.0=6”); 模式a=Pattern.compile(“…rld!”); 模式b=Pattern.comp

如果调用
scanner.hasNext(pattern)
,然后调用
scanner.next(pattern)
java.util.scanner

假设我有很多案例的代码(尝试制作lexer):

import java.util.*;
导入java.util.regex.Pattern;
公共类主类{
公共静态void main(字符串[]args){
扫描仪=新扫描仪(“你好,世界!3+3.0=6”);
模式a=Pattern.compile(“…rld!”);
模式b=Pattern.compile(“…llo”);
while(scanner.hasNext()){
if(扫描器hasNext(a)){
下一步(a);
/*用它做一些有意义的事情,比如创建一个令牌*/
}
else if(scanner.hasNext(b)){
下一步(b);
}
/*...*/
}
//关闭扫描仪
scanner.close();
}
}
我的问题是:

  • hasNext(模式)
    是否以某种方式缓存搜索结果?所以它不会搜索同一个模式两次
  • 这比使用
    try{scanner.next(pattern)}catch{…}
  • 或者有没有更简单的方法(没有第三方库)基于regex模式进行标记化

    • 好的,所以我认为答案是:

      文档并没有说任何事情,所以它可能是可能的,但它可能没有


      另外,我问这个问题主要是因为我想用它来解析更复杂的东西,比如字符串文本,而不仅仅是空格分隔的标记。
      发现扫描器仍然使用这样的令牌,然后检查它是否匹配。因此,它现在对我的用例毫无用处。

      这是否回答了您的问题?可惜没有。问题不是用空格分隔,而是从输入中获取一个令牌,但不知道下一个将出现哪个令牌。因此需要多个正则表达式,我需要单独检查。我不能跳过空白的原因是我也需要解析字符串,这样我就不知道跳过了多少个正则表达式了。所以我发现扫描器仍然需要跳过空白,所以现在没用了。我建议使用解析器生成器。您定义语法,生成器生成java解析器。这里有一个例子:谢谢你的选择。但不幸的是,我需要一个学校项目,我们必须使用标准的java和scala库。但我还是要感谢你为其他偶然发现这个问题的人提供了一个非常有用的信息:-)那么我建议:1。列出令牌模式。2.创建包含捕获组3的正则表达式。如果您将捕获组名和正则表达式保存在一个类中,您可以很好地重用它们,请使用这些组来确定令牌类型:这正是我所做的,但不是使用scanner。我用BufferedReader定制了一个与模式匹配的类。我无法使用Scanner执行此操作的原因是Scanner在执行任何匹配之前使用分隔符并将输入拆分为单独的标记。起初,我并没有预料到这一点,但如果我试图在包含
      0x32
      的输入上匹配一个模式与
      [0-9]+
      ,它就不会识别它。这让我相信它不会识别模式
      “[^”]+”
      ,输入看起来像
      “hello world”