java.io.StreamTokenizer在遇到下划线时生成空令牌



我有一个用于解析令牌的StreamTokenizer。当我将以下内容传递到stdin时:

a b_c d

解析的令牌(在stdout上)是:

a
b
null
c
d

为什么会这样?如果下划线是一个单词字符,则应该有3个标记,第二个标记为"b_c"。如果下划线是分隔符,则应该有4个标记。我认为空标记没有任何意义。

Q1:为什么会有空令牌?

Q2:为什么有人会设计一个StreamTokenizer来产生空令牌?

Ideone脚本:http://ideone.com/e.js/RFbPpJ

import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StreamTokenizer st = new StreamTokenizer(br);
        while (st.nextToken() != StreamTokenizer.TT_EOF) {
            System.out.println(st.sval);
        }
    }
}

来自文档:

如果当前标记是单词标记,则此字段包含一个字符串给出单词记号的字符。当当前令牌是带引号的字符串标记,此字段包含字符串的正文。这个当前标记是ttype字段的值为TT_word时的单词。当ttype的值字段是一个引号字符。

此字段的初始值为null。

这意味着不满足任何条件并且输出CCD_ 1。

换句话说,下划线的ttype既不是一个单词,也不是一个带引号的字符串。

ttype的文档指定

在调用nextToken方法之后,此字段包含令牌刚刚读取。对于单字符令牌,其值为单个字符,转换为整数。对于引用的字符串令牌,它的值是引号字符。否则,其值为如下:TT_WORD表示令牌是一个单词。TT_NUMBER指示令牌是一个数字。TT_EOL表示行已被读取。只有当eolIsSignificant方法已被调用,参数为true。TT_EOF指示已经到达输入流的末尾。

该字段的初始值为-4。

请注意,-4值等于TT_NOTHING。

要将下划线识别为单词,可以使用tokenizer.wordChars('_', '_');

wordChars用于指定范围low<c<=high是单词成分。单词标记由一个单词组成后面跟零个或多个单词成分或数字的成分成分。

如果你希望下划线是一个普通的字符而不是单词字符,那么也有一个方法。

请注意,将"_"同时作为wordChars的分隔符将只允许下划线为单词字符,因此您可能需要设置适合您需要的边界。

编辑:为了回答您的评论,简而言之,下划线被视为标识符的一部分,这就是为什么它没有映射到任何内容,因此返回null。

如果您查看StreamTokenizer类的未记录的私有构造函数,您将更好地了解如何处理每个字符:

private StreamTokenizer() {
    wordChars('a', 'z');
    wordChars('A', 'Z');
    wordChars(128 + 32, 255);
    whitespaceChars(0, ' ');
    commentChar('/');
    quoteChar('"');
    quoteChar(''');
    parseNumbers();
}

下划线是ASCII代码95,它不在边界内。

相关内容

  • 没有找到相关文章

最新更新