如何处理含分隔符的CSV字段?用Joinery DataFrame保留含;的单值
解决Joinery读取含分隔符字段的CSV问题
你遇到的核心问题是:CSV文件用;作为分隔符,但某条记录的字段值(s;m)包含该分隔符且未用引号包裹,导致Joinery默认按;分割时会拆分这个字段,破坏原有数据结构。
方案1:要求源系统输出符合CSV规范的文件(最优解)
根据CSV规范,包含分隔符的字段必须用引号包裹。如果能协调外部系统将异常行修改为:
"s;m";30;12345
只需调整Joinery的readCsv调用,指定引号字符为双引号即可:
DataFrame abc = DataFrame.readCsv(inputStream, ";", "\"", Boolean.TRUE);
此时Joinery会自动识别引号内的内容为单个字段,忽略其中的;分隔符。
方案2:预处理数据流(无法修改源数据时使用)
如果外部系统无法调整输出格式,需要先对输入流进行预处理,修复异常行:
- 逐行读取CSV内容
- 判断行分割后的列数:正常行应为3列,异常行是4列
- 将异常行的前两个字段合并为
s;m,恢复为3列结构 - 将处理后的内容重新转为输入流,再交给Joinery读取
示例代码:
import java.io.*; import java.nio.charset.StandardCharsets; import joinery.DataFrame; public class CsvPreprocess { public static void main(String[] args) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder processedContent = new StringBuilder(); // 写入表头 String header = reader.readLine(); if (header != null) { processedContent.append(header).append("\n"); } String line; while ((line = reader.readLine()) != null) { String[] parts = line.split(";", -1); if (parts.length == 4) { // 合并前两个字段,恢复为3列结构 String mergedField = parts[0] + ";" + parts[1]; processedContent.append(mergedField) .append(";") .append(parts[2]) .append(";") .append(parts[3]) .append("\n"); } else { // 正常行直接保留 processedContent.append(line).append("\n"); } } // 将处理后的内容转为输入流 InputStream processedStream = new ByteArrayInputStream(processedContent.toString().getBytes(StandardCharsets.UTF_8)); // 读取处理后的CSV DataFrame abc = DataFrame.readCsv(processedStream, ";", "", Boolean.TRUE); } }
注意:该方法依赖数据的固定规律(异常行都是4列,且需合并前两个字段),若后续出现其他位置的含分隔符字段,需对应调整合并逻辑。
内容的提问来源于stack exchange,提问作者shrikish
相关产品推荐
相关产品推荐

