2

分割コマンドの後に文字列"MO""RET"が配列に格納されます。items[1]保存された後、この文字列に対して replaceall を実行すると、すべての二重引用符が置き換えられます。しかし、私はそれをとして保存したいMO"RET。どうすればいいのですか。分割コマンドを使用して処理する csv ファイルでは、テキスト フィールドの内容内で二重引用符が繰り返されます (例: このアカウントは""large""1 つです")。 get が繰り返され、終了引用符が存在する場合は無視されます。

String items[] = line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");
items[1] has "MO""RET"
String recordType = items[1].replaceAll("\"","");

このrecordTypeが持っている後、私はMORET それが欲しいMO"RET

4

4 に答える 4

6

正規表現を使用して CSV 行を分割しないでください。これは問題を引き起こしています ;) 文字ごとに解析するだけです。次に例を示します。

public static List<List<String>> parseCsv(InputStream input, char separator) throws IOException {
    BufferedReader reader = null;
    List<List<String>> csv = new ArrayList<List<String>>();
    try {
        reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
        for (String record; (record = reader.readLine()) != null;) {
            boolean quoted = false;
            StringBuilder fieldBuilder = new StringBuilder();
            List<String> fields = new ArrayList<String>();
            for (int i = 0; i < record.length(); i++) {
                char c = record.charAt(i);
                fieldBuilder.append(c);
                if (c == '"') {
                    quoted = !quoted;
                }
                if ((!quoted && c == separator) || i + 1 == record.length()) {
                    fields.add(fieldBuilder.toString().replaceAll(separator + "$", "")
                        .replaceAll("^\"|\"$", "").replace("\"\"", "\"").trim());
                    fieldBuilder = new StringBuilder();
                }
                if (c == separator && i + 1 == record.length()) {
                    fields.add("");
                }
            }
            csv.add(fields);
        }
    } finally {
        if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
    }
    return csv;
}

はい、関係する正規表現はほとんどありませんが、単一フィールドの末尾の区切り記号と周囲の引用符のみを削除します。

ただし、サードパーティのJava CSV APIを取得することもできます。

于 2010-02-11T02:57:14.787 に答える
1

どうですか:

String recordType = items[1].replaceAll( "\"\"", "\"" );
于 2010-02-11T02:55:50.510 に答える
0

replaceAll の代わりに replace を使用することをお勧めします。replaceAll は最初の引数として REGEX を使用します。

要件は、2 つの連続する QUOTES を 1 つの QUOTE に置き換えることです。

String recordType = items[1].replace( "\"\"", "\"" );

replace と replaceAll の違いを確認するには、次のコードを実行します

recordType = items[1].replace( "$$", "$" );
recordType = items[1].replaceAll( "$$", "$" );
于 2010-02-11T03:22:10.020 に答える
0

Here you can use the regular expression.

recordType = items[1].replaceAll( "\\B\"", "" ); 
recordType = recordType.replaceAll( "\"\\B", "" ); 

First statement replace the quotes in the beginning of the word with empty character. Second statement replace the quotes in the end of the word with empty character.

于 2010-02-11T07:08:45.337 に答える