Java 不带分隔符的扫描仪

Java 不带分隔符的扫描仪,java,java.util.scanner,Java,Java.util.scanner,我希望能够像下面这样解析字符串:“123456abcd9876az45678”。BNF是这样的: number: ? definition of an int ? word: letter { , letter } expression: number { , word , number } 但是,类java.util.scanner不允许我执行以下操作: Scanner s = new Scanner("-123456abcd9876az45678"); System.out.println

我希望能够像下面这样解析字符串:“123456abcd9876az45678”。BNF是这样的:

number: ? definition of an int ?
word: letter { , letter }
expression: number { , word , number }
但是,类java.util.scanner不允许我执行以下操作:

Scanner s = new Scanner("-123456abcd9876az45678");
System.out.println(s.nextInt());
while (s.hasNext("[a-z]+")) {
    System.out.println(s.next("[a-z]+"));
    System.out.println(s.nextInt());
}
理想情况下,这将产生:

-123456
abcd
987
az
45678
我真的希望java.util.Scanner能帮助我,但看起来我必须创建自己的扫描仪。Java API中已经有什么东西可以帮助我了吗



这个问题遗漏了太多信息。因此,所有答案都对问题有效,但对我的问题无效。

您可以使用和类来实现这一点。请参见示例。

不幸的是,您不能对Scanner类AFAIK使用任何分隔符。如果希望忽略分隔符,则需要使用这样做的方法,例如
findInLine()
findWithinHorizon()
。在您的情况下,
findwhinhorizion()
将是适当的

Scanner s = new Scanner("-123456abcd9876az45678");
Pattern num = Pattern.compile("[+-]?\\d+");
Pattern letters = Pattern.compile("[A-Za-z]+");
System.out.println(s.findWithinHorizon(num, 0));
String str;
while ((str = s.findWithinHorizon(letters, 0)) != null) {
    System.out.println(str);
    System.out.println(s.findWithinHorizon(num, 0));
}

要将扫描仪用作标记器,请使用
findWithinHorizon
\G
仅从组开始(=当前位置)进行扫描

支持空白的示例(如注释中所要求):


在实际应用程序中,您可能应该预先编译模式。

您可以将分隔符设置为与任何内容都不匹配的模式,例如

Scanner s = ...
s.useDelimiter("(?!=a)a");

我不知道这段代码应该做什么,但我想你应该用[a-z]*而不是[a-z]好的,完整的常见情况是下面的“4d8-1d4+20”被解析为两个骰子+一个常量。可能有更多的骰子卷,可能没有,可能有空格或没有。底线是我想在没有任何分隔符的情况下动态地更改令牌。我也不想被重定向到中常见的骰子符号线程,因为它不能帮助我处理他们正在使用的所有这些求值函数。我想建立骰子表达式的树。不,正则表达式不会这么做。请参阅我在问题下的评论。您的评论没有向我解释为什么模式/匹配器习惯用法不够。对不起,完整地说,我想要比正则表达式更好、更具可塑性的东西。在我的例子中,正则表达式完全是过度使用,耗尽了我所期望的灵活性。无论如何谢谢你!好主意,但我不能用这个来构建语言。我的意思是,如果我再次搜索,它将跳过所有,以便找到号码。我想我必须为这个做我自己的扫描仪。@Frór:它和你给我们的例子没有太大区别,只是它符合你的规格。当然,除非你遗漏了一些你需要的其他细节。是的,我认为还有一些其他的要求是微不足道的。我现在正在考虑删除整个问题,重新创建一个新的问题,并对该问题进行全面概述。
Scanner s = ...
s.useDelimiter("(?!=a)a");