2

在 split 命令之后,我将字符串"MO""RET"存储在items[1]数组中。在它被存储之后,我在这个字符串上做了一个替换,它替换了所有的双引号。但我希望它存储为MO"RET. 我该怎么做。在我使用拆分命令处理的csv文件中,重复文本字段内容中的双引号(例如:此帐户是""large""一个“)。所以我想保留字符串中间的两个引号之一,如果它重复获取并忽略结尾引号(如果存在)。我该怎么做?

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

在此记录类型之后,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;
}

是的,涉及的正则表达式很少,但它只修剪单个字段的结尾分隔符和周围的引号。

但是,您也可以获取任何 3rd 方Java CSV API

于 2010-02-11T02:57:14.787 回答
1

怎么样:

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

在这里您可以使用正则表达式。

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

第一条语句用空字符替换单词开头的引号。第二个语句用空字符替换单词末尾的引号。

于 2010-02-11T07:08:45.337 回答
0

我更喜欢你使用replace 而不是replaceAll。replaceAll 使用 REGEX 作为第一个参数。

要求是用一个 QUOTE 替换两个连续的 QUOTES

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

要查看 replace 和 replaceAll 之间的区别,请执行以下代码

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