1
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);
    }
}

您好,我正在使用标记器来读取一行的内容并将其存储到一个 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

有任何想法吗?

4

4 回答 4

2

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

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

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

于 2012-06-26T15:46:47.973 回答
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

据我了解,这是您的标记器代码工作所需的预处理。希望这可以帮助。

于 2012-06-26T16:06:06.607 回答
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);
    }
}
于 2012-06-26T15:48:43.543 回答
1

如您所见,在类描述中,Oracle 不鼓励使用StringTokenizer 。我不会使用标记器,而是使用 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]);

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

于 2012-06-26T16:27:03.383 回答