我想使用手写的降序解析器解析一些文本。我使用Scanner
了以下分隔符:"\\s*"
. 不幸的是,这个模式匹配一个空字符串这一事实似乎使every hasNextFoo
and nextFoo
match 不再匹配。
该文档没有说明可能为空的分隔符。
我想使用手写的降序解析器解析一些文本。我使用Scanner
了以下分隔符:"\\s*"
. 不幸的是,这个模式匹配一个空字符串这一事实似乎使every hasNextFoo
and nextFoo
match 不再匹配。
该文档没有说明可能为空的分隔符。
您也可以考虑StreamTokenizer。这是在递归下降解析器中将其用于单符号前瞻的示例。
是的,因为我想将扫描仪用作运行时词法分析器。简而言之,我希望能够询问scanner.next(pattern),它要么返回匹配的字符串,要么在不消耗流的情况下返回异常。空格应该被忽略。如果有比扫描仪更好的课程,我会很高兴使用它。
我想不出任何现成的库类可以为你做到这一点。扫描器/词法分析器的正常模型是任何无效的字符序列(即导致异常的字符序列)都将被消耗。因此,我认为您将不得不手动实现自己的扫描仪,注意将预读字符视为未使用的字符。您可以使用“后推”阅读器或(如果该模型不方便)通过使用某种标记/重置模型自己显式缓冲字符来做到这一点。如果您所做的只是拆分为由一个或多个空格分隔的标记,那么推回阅读器方法应该没问题。
您对“+”字符有异议吗?
您确定要使用正则表达式,而不仅仅是测试空格字符的 if 语句吗?你说'运行时'。您的数据是在字符串中,还是在流中,还是什么?
可以使用lookbehinds/lookaheads 来明确定义哪些分隔符是可省略的。
例如,此扫描仪使用空格作为分隔符,但在数字和单词之间不需要它们:
new Scanner("1A.23 4 BC-5")
.useDelimiter("\\s+|(?<=\\d)(?=[A-Z])|(?<=[A-Z])(?=[-+.\\d])");
它产生:
1
A
.23
4
BC
-5
正则表达式由三个交替组成:
\s+
连续的空格是分隔符。(?<=\d)(?=[A-Z])
数字和字母之间的空字符串是分隔符。(?<=[A-Z])(?=[-+.\d])
字母和 '-'、'+'、'.' 之间的空字符串 或数字是分隔符。(注意:\w
不能在这里使用,因为它匹配数字。)