Java StreamTokenizer在@符号

时间:2015-05-31 14:59:59

标签: java email stream tokenize

我正在尝试解析包含电子邮件地址的文档,但StreamTokenizer将电子邮件地址拆分为两个独立的部分。

我已将@符号设置为ordinaryChar,将空格设置为唯一的whitespace

StreamTokenizer tokeziner = new StreamTokenizer(freader);
tokeziner.ordinaryChar('@');
tokeziner.whitespaceChars(' ', ' ');

但是,所有电子邮件地址都被拆分了。

要解析的行如下所示:

"Student 6 Name6 LastName6 del6@uni.at  Competition speech University of Innsbruck".

Tokenizer将del6@uni.at拆分为"del6""uni.at"

有没有办法告诉标记器不要在@标志处分开?

2 个答案:

答案 0 :(得分:2)

所以这就是为什么它像它一样工作的原因:

StreamTokenizer将其输入视为编程语言标记器。也就是说,它会将其分解为以下标记:"单词","数字","引用字符串","注释"等等on,基于程序员为其设置的语法。程序员告诉它哪些字符是单词字符,普通字符,注释字符等。

所以实际上它做了相当复杂的标记化 - 识别注释,引用字符串,数字。请注意,在编程语言中,您可以使用a = a+b;之类的字符串。一个简单的标记化器只会按空格分隔文本,会将其分为a=a+b;。但是StreamTokenizer会将其分为a=a+b;,还会给你"类型"对于这些令牌中的每一个,所以你的语言"解析器可以区分标识符和运算符。 StreamTokenizer的类型相当基本,但这种行为是理解您案例中发生的事情的关键。

它没有将@识别为空格。实际上,它正在解析它并将其作为令牌返回。但它的价值在ttype字段中,您可能只是在看sval

StreamTokenizer会将您的行识别为:

The word Student
The number 6.0
The word Name6
The word LastName6
The word del6
The character @
The word uni.at
The word Competition
The word speech
The word University
The word of
The word Innsbruck

(这是我写的一个标记你的示例行并按类型打印的小演示的实际输出。)

事实上,通过告诉它@是一个"普通字符",你告诉它将@作为自己的令牌(默认情况下它仍会这样做) )。 ordinaryChar() documentation告诉您此方法:

  

指定字符参数是"普通"在这个标记器中。   它删除了角色作为评论的任何特殊意义   字符,单词组件,字符串分隔符,空格或数字   字符。 当解析器遇到这样的字符时,   解析器将其视为单字符标记并将ttype字段设置为   字符值。

(我的重点)。

事实上,如果您将其传递给wordChars(),就像tokenizer.wordChars('@','@')一样,它会将整个电子邮件保存在一起。我添加的小演示提供了:

The word Student
The number 6.0
The word Name6
The word LastName6
The word del6@uni.at
The word Competition
The word speech
The word University
The word of
The word Innsbruck

如果您需要类似编程语言的标记器,StreamTokenizer可能适合您。否则,您的选项取决于您的数据是否基于行(每行是一个单独的记录,每行上可能有不同数量的令牌),您通常会从阅读器逐个读取行,然后拆分他们使用String.split(),或者如果它只是一个以空格分隔的标记链,Scanner可能更适合你。

答案 1 :(得分:1)

为了简单地拆分select yourfields from pizza join pizza_topping pt1 on pizza.pizzaID = pt1.pizzaID join topping t1 on pt1.toppingID = t1.toppingId join pizza_topping pt2 on pizza.pizzaID = pt2.pizzaID join topping t2 on pt2.toppingID = t2.toppingId where t1.toppingName = 'topping1' and t2.toppingName = 'topping2' ,请参阅the answerthis question(适用于空白):

  

最好的方法是根本不使用StringTokenizer,而是使用String   分裂方法。它返回一个字符串数组,你可以得到   长度。

     

对于文件中的每一行,您可以执行以下操作:

     

String [] tokens = line.split(“+”);

     

令牌现在将有6到8个字符串。使用tokens.length()来查找   多少,然后从数组中创建你的对象。

这对于给定的行是足够的,并且可能足以满足一切。以下是一些使用它的代码(它显示为String):

System.in