手动解析CSV文件v2.0

本文详细讲述了在CSV文件中遇到包含英文逗号的数据如何使用Java进行解析,通过实例演示了如何识别复合体和普通单元格,并展示了关键的逻辑和标记方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前提:这里考虑的各个单元格数据都不为空。

一、背景

实际的csv文件是用英文逗号分隔的,是一个简单的文本,但是如果单元格内的数据本身就包含英文逗号呢?
在这里插入图片描述
以上这种情况,保存的文本大概是这个样子:

张三,"3500,4500","唱歌,游泳,骑马,"

二、解析

下面使用java进行手动解析:

public class App {

    public static void main(String[] args) {
        // 张三,"3500,4500","唱歌,游泳,骑马,"
        final String str = "张三,\"3500,4500\",\"唱歌,游泳,骑马,\"";
        System.out.println(str);
        final char[] arr = str.toCharArray();
        int start = 0;
        // 表示一个单元格内的数据就包含,
        boolean complex = false;
        int len = arr.length;
        for (int i = 0; i < len; i++) {
            char c = arr[i];
            if (c == '"') { // 表示一个复合体的开始或者结束
                if (complex) {
                    // 已经设置过complex标志,说明当前是一个复合体的结束"
                    final String item = new String(arr, start, i - start);
                    System.out.println(item);
                    complex = false;
                    i++;
                } else {
                	// 未设置过complex标志,说明当前是一个复合体的开始"
                    start = i + 1;
                    complex = true;
                }
            } else if (c == ',' && !complex) { // 一个普通单元格的结束
                final String item = new String(arr, start, i - start);
                System.out.println(item);
                start = i + 1;
            }
        }
    }

}

控制台打印的内容:

张三,"3500,4500","唱歌,游泳,骑马,"
张三
3500,4500
唱歌,游泳,骑马,

三、思路

名词解释:
复合体:这里指的是数据中就包含英文逗号,的单元格。
普通单元格:这里指的是数据中不包含英文逗号,的单元格。

解析张三,"3500,4500","唱歌,游泳,骑马,"这行csv数据,基本原理还是将它转换为char[]字符数组,从头到尾逐个字符查看,对特殊字符进行标记、记录,这里特殊标记包括:

  1. 英文逗号,,它可能表示一个普通单元格的结束,也可能只是复合体中的一个普通字符
  2. 英文分号",它用来将一个复合体包裹起来,表示一个复合体的开始或者是结束

对于一个单元格的数据,我需要知道它从哪里开始,即这里的start变量值,到哪里结束,这里就是检测到结束的i的位置,然后从arr字符数组中构建一个String,就得到了一个单元格的数据。

对于普通字符,不需要标记,跳过即可,考虑上面提到的两个特殊标志:

  1. 对于,来说,如果当前的complexfalse,说明之前并没有碰到复合体,那么它就是一个单元格数据的结束了,可以构建一个String,并且可以预见下一个字符就应该是另一个单元格数据的开始,那么就需要将它设置为start = i + 1,其实它并不完全正确,因为下一个有可能是特殊标记",但是它会被下面的这种情况所修正
  2. 对于"来说,它有可能表示复合体的开始或者结束,这里使用一个布尔值complex来进行区分,如果complex的值为true,说明当前遇到一个"标记,并且之前也碰到一个"才会使得complex的值为true,即可以构建一个final String item = new String(arr, start, i - start)。同时需要设置complex的值为false,让它失效,同时紧挨着的下一个,没有意义,手动跳过它:i++。如果complex的值为false,说明是第一个遇到",表示复合体的开始,只需要设置start = i + 1,同时设置complex = true使之生效。

that’s all
thanks for reading~
111

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值