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) 方法的麻烦/困惑的主要内容,如果未能解决你的问题,请参考以下文章