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

こんにちは、トークナイザーを使用して行の内容を読み取り、配列リストに保存しています。ここでは、GrabData クラスがその役割を果たします。

唯一の問題は、会社名 (各行の 3 列目) が引用符で囲まれ、カンマが含まれていることです。あなたの例のために1行を含めました。トークナイザーはコンマに依存して、行を異なるトークンに分割します。しかし、会社名はそれを捨てると思います。会社の列にコンマがなければ、すべてが正常に機能します。

例:- 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

これは、正規表現を使用して実現できます。次のコード:

        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 に答える
2

まず、StringTokenizer はレガシー コードと見なされます。Javaドキュメントから:

StringTokenizer は、新しいコードでの使用は推奨されていませんが、互換性のために保持されているレガシー クラスです。この機能が必要な場合は、代わりに String の split メソッドまたは java.util.regex パッケージを使用することをお勧めします。

split() メソッドを使用して、文字列の配列を取得します。配列を繰り返し処理しているときに、現在の文字列が引用符で始まっているかどうかを確認できます。そうであれば、次の文字列が引用符で終わっているかどうかを確認できます。これらの 2 つの条件を満たしている場合は、必要な場所で分割していないことがわかり、これら 2 つをマージして、必要に応じて処理し、その後、配列を通常どおり反復処理し続けることができます。そのパスでは、おそらく通常の i++ の代わりに i+=2 を実行し、気付かれないはずです。

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

ご覧のとおり、クラスの説明では、StringTokenizerの使用はOracleによって推奨されていません。トークナイザーを使用する代わりに、引数として正規表現を使用してコードを大幅に削減できる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 に答える