我正在尝试解析包含电子邮件地址的文档,但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"
。
有没有办法告诉标记器不要在@
标志处分开?
答案 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 answer至this question(适用于空白):
最好的方法是根本不使用StringTokenizer,而是使用String 分裂方法。它返回一个字符串数组,你可以得到 长度。
对于文件中的每一行,您可以执行以下操作:
String [] tokens = line.split(“+”);
令牌现在将有6到8个字符串。使用tokens.length()来查找 多少,然后从数组中创建你的对象。
这对于给定的行是足够的,并且可能足以满足一切。以下是一些使用它的代码(它显示为String
):
System.in