使用tokenizer读取一行

时间:2012-06-26 15:35:12

标签: java tokenize readline stringtokenizer

public void GrabData() throws IOException
{
    try {
        BufferedReader br = new BufferedReader(new FileReader("data/500.txt"));
        String line = "";
        int lineCounter = 0;
        int TokenCounter = 1;
        arrayList = new ArrayList < String > ();

        while ((line = br.readLine()) != null) {

            //lineCounter++;
            StringTokenizer tk = new StringTokenizer(line, ",");

            System.out.println(line);

            while (tk.hasMoreTokens()) {
                arrayList.add(tk.nextToken());
                System.out.println("check");
                TokenCounter++;

                if (TokenCounter > 12) {
                    er = new DataRecord(arrayList);
                    DR.add(er);
                    arrayList.clear();
                    System.out.println("check2");

                    TokenCounter = 1;
                }

            }
        }
    } catch (FileNotFoundException ex) {
        Logger.getLogger(Driver.class.getName()).log(Level.SEVERE, null, ex);
    }
}

您好,我正在使用tokenizer来读取行的内容并将其存储到araylist中。这里GrabData类完成了这项工作。

唯一的问题是公司名称(每行中的第三列)都在引号中并且在其中有逗号。我为你的例子添加了一行。标记生成器依赖于逗号将行分成不同的标记。但我猜这个公司的名字就把它抛下了。如果不是公司专栏中的逗号,一切都正常。

实施例: - Essie,Vaill,“Litronic,Industries”,14225 Hancock Dr,Anchorage,Anchorage,AK,99515,907-345-0962,907-345-1215,essie @ vaill.com,http://www.essievaill.com < / p>

有什么想法吗?

4 个答案:

答案 0 :(得分:2)

首先,StringTokenizer被认为是遗留代码。来自Java doc:

  

StringTokenizer是一个遗留类,出于兼容性原因而保留,尽管在新代码中不鼓励使用它。建议任何寻求此功能的人都使用String的split方法或java.util.regex包。

使用split()方法可以得到一个字符串数组。在迭代数组时,您可以检查当前字符串是否以引号开头,如果是这种情况,请检查下一个字符串是否以引号结尾。如果你满足这两个条件,那么你知道你没有拆分你想要的地方,你可以将这两个合并在一起,按照你想要的方式处理它,并在此之后继续正常迭代数组。在那个传球中,你可能会做i + = 2而不是常规的i ++,它应该被忽视。

答案 1 :(得分:2)

您可以使用正则表达式完成此操作。以下代码:

        String s = "asd,asdasd,asd\"asdasdasd,asdasdasd\", asdasd, asd";
        System.out.println(s);
        s = s.replaceAll("(?<=\")([^\"]+?),([^\"]+?)(?=\")", "$1 $2");
        s = s.replaceAll("\"", "");
        System.out.println(s);

产量

asd,asdasd,asd, "asdasdasd,asdasdasd", asdasd, asd
asd,asdasd,asd, asdasdasd asdasdasd, asdasd, asd

根据我的理解,这是您的tokenizer代码工作所需的预处理。希望这会有所帮助。

答案 2 :(得分:1)

虽然StringTokenizer本身可能无法为你处理这个问题,但是有几行代码可以做到这一点......可能不是最有效的,但是应该把这个想法贯彻......

while(tk.hasMoreTokens()) {
    String token = tk.nextToken();

    /* If the item is encapsulated in quotes, loop through all tokens to 
     * find closing quote 
     */
    if( token.startsWIth("\"") ){
        while( tk.hasMoreTokens() && ! tk.endsWith("\"") ) {
            // append our token with the next one.  Don't forget to retain commas!
            token += "," + tk.nextToken();
        }

        if( !token.endsWith("\"") ) {
            // open quote found but no close quote.  Error out.
            throw new BadFormatException("Incomplete string:" + token);
        }

        // remove leading and trailing quotes
        token = token.subString(1, token.length()-1);
    }
}

答案 3 :(得分:1)

如您所见,在类描述中,Oracle不鼓励使用StringTokenizer。 我不使用tokenizer而是使用String split()方法 您可以使用正则表达式作为参数,并显着减少您的代码。

    String str = "Essie,Vaill,\"Litronic , Industries\",14225 Hancock Dr,Anchorage,Anchorage,AK,99515,907-345-0962,907-345-1215,essie@vaill.com,http://www.essievaill.com";
    String[] strs = str.split("(?<! ),(?! )");
    List<String> list = new ArrayList<String>(strs.length);

    for(int i = 0; i < strs.length; i++) list.add(strs[i]);

请注意你的正则表达式,使用这个你假设逗号总是在空格之间。