Java.util.Scanner next(Pattern) 方法的麻烦/困惑

Posted

技术标签:

【中文标题】Java.util.Scanner next(Pattern) 方法的麻烦/困惑【英文标题】:Trouble With/Confused By Java.util.Scanner's next(Pattern) Method 【发布时间】:2009-08-16 20:22:05 【问题描述】:

我已经构建了一个正则表达式,我将其编译为一个模式来查找 Fortran Real*8 数字。棘手的一点是我正在读取的文件是一行有几百万列.. 当我这样做时:

Scanner recordScanner = new Scanner(recordString);
String foundReal = recordScanner.findInLine(real8Regex);

我得到了我正在寻找的东西,但是当我使用 next(Pattern) 方法时,我得到一个 InputMismatchException.. 奇怪,考虑到 findInLine 和 next 返回字符串。

Scanner recordScanner = new Scanner(recordString);
String foundReal = recordScanner.next(real8Regex);

在使用 next() 方法时我是否遗漏了一些重要的东西?

【问题讨论】:

【参考方案1】:

这是“并非所有标记都与模式匹配,因此 next(Pattern) 卡在第一个不匹配标记”的问题吗?

next(Pattern) 可以这样使用:

String toSearch = "ab123d4e::g67f912g34h";
Scanner aScanner = new Scanner(toSearch);
aScanner.useDelimiter("[a-z]+");
while (aScanner.hasNext("[0-9]+"))

    System.out.println(aScanner.next("[0-9]+"));

但只会输出 123 和 4,因为不匹配的第三个标记会导致 while 循环终止。但是,在这种情况下,我应该只使用hasNext()next()

我一直在努力寻找使用next(Pattern) 的真正理由,因为它会卡在与模式不匹配的第一个标记上。 next(Pattern) 不是的意思是“返回当前位置之后匹配模式的第一个标记”;它的意思是“如果它与 Pattern 匹配,则返回序列中的下一个标记;否则什么都不做”

您(大概)需要读入所有令牌,因此最好使用hasNext()next(),然后针对每个令牌所需的Pattern 使用Matcher

最后,你会发现question 842496很有用

【讨论】:

【参考方案2】:

在我看来,文档写得并不出色,但它正在做它应该做的事情。

next(pattern) 被记录为返回令牌如果它是在扫描仪的当前位置找到的。如果模式在当前行中不匹配,findInLine(pattern) 被记录为返回 null

要先检查,请在调用next(pattern) 之前使用hasNext(pattern)

【讨论】:

感谢您的回复,w当我尝试使用 hasNext(Pattern) 时,应用程序找不到任何东西...如果我用 while 循环包围 if(hasNext(Pattern)) 条件Scanner.hasNext() (如果有另一个基于我的分隔符的标记,即空格,则为真),代码只会占用 CPU 周期,但从不返回结果。 是的,因为 hasNext 不会推进扫描仪。我不清楚你真正想要实现什么。一些示例代码会有所帮助。【参考方案3】:

我有点晚了(你应该把它标记为“正则表达式”),但你应该使用

String foundReal = recordScanner.findWithinHorizon(real8Regex, 0);

通过使用findInline(real8Regex),您可以让扫描器进行大量不必要的处理,以确保当前匹配与上一个匹配在同一行。您的数据都在一条线上这一事实正是您不应该使用findInLine()的原因。

【讨论】:

以上是关于Java.util.Scanner next(Pattern) 方法的麻烦/困惑的主要内容,如果未能解决你的问题,请参考以下文章

Scanner对象next与nextLine

用户键盘输入模块java.util.Scanner

我在这里做错了什么?

java.util.Scanner的使用

关于java的scanner类

Java 控制台输入