2009-12-25 132 views
1

我想使用手写降序解析器解析某些文本。我用以下分隔符Scanner"\\s*"。不幸的是,这种模式匹配空字符串的事实似乎使每个hasNextFoonextFoo都不再匹配。带空分隔符的Java扫描器

该文档没有提及可能为空的分隔符。

回答

1

你对“+”字符有一些反对意见吗?

是否确定要使用正则表达式,而不仅仅是测试空间字符的if语句?你说'运行时'。你的数据是字符串,还是来自一个流,或者什么?

+0

可爱。我相信@bmargulies试图说的是,+角色将匹配“至少一个”,“而不是一个或多个”。这将阻止它匹配一个空字符串。 – GrayWizardx 2009-12-25 23:21:51

+0

是的,因为我想用扫描仪作为运行时间词法分析器。总之,我想能够问'扫描仪。next(pattern)',它会返回匹配的字符串,或者在不使用流的情况下返回异常。空间应该被忽略。如果比扫描仪有更好的课程,我会很乐意使用它。 – 2009-12-25 23:29:42

+0

所有的开玩笑,@垃圾回答可能是想要的。你真的没有给我们足够的背景去继续。 – bmargulies 2009-12-25 23:51:14

1

是的,因为我想用扫描仪作为运行时间词法分析器。简而言之,我希望能够询问scanner.next(pattern),它将返回匹配的字符串,或者在不使用流的情况下返回异常。空间应该被忽略。如果比扫描仪有更好的课程,我会很乐意使用它。

我想不出任何现成的库类会为你做到这一点。扫描仪/词法分析器的普通模型是任何无效的字符序列(即导致异常的字符序列)都将被消耗。所以,我认为你将不得不亲自实施自己的扫描仪,注意将未读的字符视为未消耗的字符。你可以用一个“回推”阅读器或者(如果这个模型不方便)通过用某种标记/重置模型自己明确缓冲字符来做到这一点。如果你正在做的是分裂成一个或多个空格分隔的令牌,那么推回阅读器的方法应该没问题。

0

可以使用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可以为它匹配的数字不能在此处使用。)