【问题标题】:Java scanner searches same pattern twiceJava 扫描器搜索相同的模式两次
【发布时间】:2013-10-06 18:59:48
【问题描述】:

我希望下面的代码会找到所有可用的模式标记。我解析了 shell 命令iwlist wlp3s0 scanning,所以总是有不止一个访问点(重复模式)。我需要以某种方式解析它们。

    Scanner s = new Scanner(commandOutput);
    String pattern = ".*?Address: (\\S*) .*?Channel:(\\d*) .*?Frequency:(\\S*) .*?Quality=(\\d*)/(\\d*) .*?Signal level=-(\\d*)";
    //s.findInLine(pattern);
    while(true){
        s.findInLine(pattern);    
        MatchResult result = s.match();
        for (int i = 1; i <= result.groupCount(); i++) {
            System.out.println(result.group(i));
        }
    }

但它会抛出这个异常:java.lang.IllegalStateException

如何在遍历循环而不是 while(true) 和异常时检查它是否有更多匹配项?

【问题讨论】:

  • 你为什么需要那个?

标签: java java.util.scanner


【解决方案1】:

问题在于match() 方法:

public MatchResult match()

返回此扫描仪执行的最后一次扫描操作的匹配结果。如果没有执行匹配,此方法抛出 IllegalStateException,或者如果最后一次匹配不成功

但为什么这是个问题?进行了一场比赛,所以只能是没有成功。让我们看一下findInLine 的文档(实际信息来自variant accepting a Pattern argument):

public String findInLine(Pattern pattern)

尝试查找指定模式忽略分隔符的下一个匹配项。 如果在下一行分隔符之前找到该模式,则扫描器会前进匹配的输入并返回与该模式匹配的字符串。如果在输入到下一行分隔符,然后返回 null 并且扫描仪的位置不变。此方法可能会阻塞等待与模式匹配的输入。

由于此方法继续在输入中搜索以查找指定的模式,因此如果不存在行分隔符,它可能会缓冲所有搜索以查找所需标记的输入。

那么这是做什么的呢?它匹配模式,并将“标记”放在匹配字符串的末尾。但这并不包含实际行中的所有内容,因此下一个 findInLine 调用将尝试匹配剩余的内容(换行符等) - 并且无法这样做......

扫描程序必须消耗所有内容直到行尾才能通过发出nextLine() 调用继续前进,而不是使用返回的字符串:

Scanner s = new Scanner(commandOutput);
String pattern = ".*?Address: (\\S*) .*?Channel:(\\d*) .*?Frequency:(\\S*) .*?Quality=(\\d*)/(\\d*) .*?Signal level=-(\\d*)";

//instead of "true, use hasNextLine()"
while(s.hasNextLine()){
    s.findInLine(pattern);    
    MatchResult result = s.match();
    for (int i = 1; i <= result.groupCount(); i++) {
        System.out.println(result.group(i));
    }
    s.nextLine(); // consume everything  from this line
}

【讨论】:

    猜你喜欢
    • 2014-12-30
    • 2012-09-02
    • 1970-01-01
    • 1970-01-01
    • 2017-12-09
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 2018-06-04
    相关资源
    最近更新 更多