我想使用手写降序解析器解析某些文本。我用以下分隔符Scanner
:"\\s*"
。不幸的是,这种模式匹配空字符串的事实似乎使每个hasNextFoo
和nextFoo
都不再匹配。带空分隔符的Java扫描器
该文档没有提及可能为空的分隔符。
我想使用手写降序解析器解析某些文本。我用以下分隔符Scanner
:"\\s*"
。不幸的是,这种模式匹配空字符串的事实似乎使每个hasNextFoo
和nextFoo
都不再匹配。带空分隔符的Java扫描器
该文档没有提及可能为空的分隔符。
你对“+”字符有一些反对意见吗?
是否确定要使用正则表达式,而不仅仅是测试空间字符的if语句?你说'运行时'。你的数据是字符串,还是来自一个流,或者什么?
您可能还会考虑StreamTokenizer。这是一个在recursive-descent parser中将其用于一个符号预览的示例。
是的,因为我想用扫描仪作为运行时间词法分析器。简而言之,我希望能够询问scanner.next(pattern),它将返回匹配的字符串,或者在不使用流的情况下返回异常。空间应该被忽略。如果比扫描仪有更好的课程,我会很乐意使用它。
我想不出任何现成的库类会为你做到这一点。扫描仪/词法分析器的普通模型是任何无效的字符序列(即导致异常的字符序列)都将被消耗。所以,我认为你将不得不亲自实施自己的扫描仪,注意将未读的字符视为未消耗的字符。你可以用一个“回推”阅读器或者(如果这个模型不方便)通过用某种标记/重置模型自己明确缓冲字符来做到这一点。如果你正在做的是分裂成一个或多个空格分隔的令牌,那么推回阅读器的方法应该没问题。
可以使用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])
数字和字母之间的空字符串是分隔符。(注:\w
可以为它匹配的数字不能在此处使用。)
可爱。我相信@bmargulies试图说的是,+角色将匹配“至少一个”,“而不是一个或多个”。这将阻止它匹配一个空字符串。 – GrayWizardx 2009-12-25 23:21:51
是的,因为我想用扫描仪作为运行时间词法分析器。总之,我想能够问'扫描仪。next(pattern)',它会返回匹配的字符串,或者在不使用流的情况下返回异常。空间应该被忽略。如果比扫描仪有更好的课程,我会很乐意使用它。 – 2009-12-25 23:29:42
所有的开玩笑,@垃圾回答可能是想要的。你真的没有给我们足够的背景去继续。 – bmargulies 2009-12-25 23:51:14