2

我希望下面的代码会找到所有可用的模式标记。我解析 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)异常时检查它是否有更多匹配项?

4

1 回答 1

1

问题在于match()方法:

公共匹配结果匹配()

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

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

公共字符串 findInLine(模式模式)

尝试查找指定模式忽略分隔符的下一个匹配项。如果在下一行分隔符之前找到该模式,则扫描程序会越过匹配的输入并返回与该模式匹配的字符串。如果在直到下一行分隔符的输入中没有检测到这样的模式,则返回 null 并且扫描仪的位置不变。此方法可能会阻止等待与模式匹配的输入。

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

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

Scanner 必须消耗所有内容,直到行尾才能通过发出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
}
于 2013-10-06T21:11:33.460 回答