You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java解析CSV时忽略引号内逗号的问题及解决方案咨询

问题分析

你手动实现的CSV分割逻辑存在两个关键问题:

  1. 循环内过早写入Set:每次处理数组元素时就调用platforms.add(words.get(2)),但此时words列表还在构建中,尚未凑齐完整的一行数据,会导致错误元素被加入,甚至可能触发索引越界。
  2. 手动解析CSV的局限性:CSV规则包含引号内逗号、转义引号("")、跨行字段等复杂场景,手动分割逻辑无法覆盖所有情况,这正是你丢失2个唯一值的核心原因。
最优解决方案:使用专业CSV解析库

不要自己造轮子,直接用Java生态中成熟的CSV解析库,比如OpenCSV,它能完美处理所有CSV标准场景,代码简洁且可靠。

步骤1:引入依赖

如果用Maven,在pom.xml中添加:

<dependency>
    <groupId>com.opencsv</groupId>
    <artifactId>opencsv</artifactId>
    <version>5.6</version> <!-- 可替换为最新稳定版 -->
</dependency>

如果用Gradle:

implementation 'com.opencsv:opencsv:5.6'

步骤2:重写解析代码

用CSVReader处理,自动处理引号内逗号等特殊情况:

import com.opencsv.CSVReader;
import java.io.FileReader;
import java.util.HashSet;

public class CsvPlatformParser {
    public static void main(String[] args) {
        String file = "FinalProject/src/Data.csv";
        HashSet<String> platforms = new HashSet<>();

        // 用try-with-resources自动关闭流,避免资源泄漏
        try (CSVReader reader = new CSVReader(new FileReader(file))) {
            reader.readNext(); // 跳过表头行
            String[] lineData;
            while ((lineData = reader.readNext()) != null) {
                // 确保列索引有效(platforms是第3列,索引从0开始为2)
                if (lineData.length > 2) {
                    platforms.add(lineData[2].trim()); // 可选:去除字段前后空格
                }
            }
        } catch (Exception e) {
            e.printStackTrace(); // 不要吞异常,方便排查问题
        }

        System.out.println("唯一平台数量:" + platforms.size());
    }
}

为什么这个方案更靠谱?

  • 自动识别引号内的逗号:比如字段"PC, PS5"会被解析为单个完整字段,不会被分割。
  • 支持转义引号:比如"John ""Doe"""会被正确解析为John "Doe"。
  • 兼容跨行字段:如果某个字段包含换行符,依然能完整读取。
  • 代码简洁,无需手动处理复杂的分割逻辑,大幅降低出错概率。
若必须手动实现(仅适合简单场景)

如果不能引入第三方库,至少要修正现有代码的逻辑:

String file = "FinalProject/src/Data.csv";
BufferedReader rd = null;
String line = "";
HashSet<String> platforms = new HashSet<>();

try {
    rd = new BufferedReader(new FileReader(file));
    rd.readLine(); // 跳过表头
    while ((line = rd.readLine()) != null) {
        String[] arr = line.split("\"");
        ArrayList<String> words = new ArrayList<>();

        for (int i = 0; i < arr.length; i++) {
            if (i % 2 == 0) {
                // 非引号部分按逗号分割,过滤空字符串(避免首尾逗号导致的无效元素)
                String[] parts = arr[i].split(",");
                for (String part : parts) {
                    if (!part.trim().isEmpty()) {
                        words.add(part.trim());
                    }
                }
            } else {
                // 引号内的内容直接加入,保留原始逗号
                words.add(arr[i].trim());
            }
        }

        // 整行解析完成后,再将有效字段加入Set
        if (words.size() > 2) {
            platforms.add(words.get(2));
        }
    }
} catch (Exception e) {
    e.printStackTrace(); // 不要吞异常
} finally {
    try {
        if (rd != null) rd.close();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

注意:这个手动实现依然无法处理转义引号、跨行字段等复杂场景,仅适用于结构简单的CSV文件。

内容的提问来源于stack exchange,提问作者scribre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:55:17