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

Scala无正则解析CSV:解决引号内逗号被split误拆分的问题

Scala无依赖修复split拆分带引号CSV单元格问题

核心思路是通过单次遍历+状态标记完成合并,全程不涉及正则和第三方依赖,逻辑非常直观:

  • 维护2个状态变量:inQuotes标记当前是否处于未闭合的引号单元格区间,currentBuffer存储当前正在拼接的不完整单元格内容
  • 遍历split(",")得到的所有数组元素,按状态处理每一段内容:
    1. 非引号状态下:
    • 若当前段以双引号开头、且未以双引号结尾:说明进入了带逗号的引号单元格,开启引号状态,将当前段写入缓冲,后续拼接时补回被拆分掉的逗号
    • 若当前段没有开头引号:说明是普通完整单元格,直接加入结果集
    1. 引号状态下:
    • 若当前段以双引号结尾:说明到达引号单元格末尾,将当前段拼入缓冲后,把缓冲内容作为完整单元格加入结果集,关闭引号状态并清空缓冲
    • 若当前段没有结尾引号:说明仍在引号单元格中间,直接拼入缓冲并补逗号即可

代码实现

def fixSplittedCsvRow(splitted: Array[String]): Array[String] = {
  import scala.collection.mutable.ListBuffer
  val result = new ListBuffer[String]()
  var inQuotes = false
  var currentBuffer = new StringBuilder()

  for (part <- splitted) {
    if (!inQuotes) {
      if (part.startsWith("\"") && !part.endsWith("\"")) {
        // 进入引号包裹的单元格,开始拼接
        inQuotes = true
        currentBuffer.append(part)
        currentBuffer.append(',') // 补回被split掉的逗号
      } else {
        // 普通完整单元格,直接加入结果,trim可根据需求保留或删除
        result.append(part.trim)
      }
    } else {
      if (part.endsWith("\"")) {
        // 到达引号单元格末尾
        currentBuffer.append(part)
        result.append(currentBuffer.toString().trim)
        // 重置状态
        inQuotes = false
        currentBuffer.clear()
      } else {
        // 仍在引号单元格中间,继续拼接
        currentBuffer.append(part)
        currentBuffer.append(',')
      }
    }
  }
  // 兼容异常格式:如果行末有未闭合的引号,把剩余缓冲加入结果
  if (inQuotes) {
    result.append(currentBuffer.toString().trim)
  }
  result.toArray
}

效果验证

使用你给出的示例测试:
输入:Array("\"Hello", " everyone\"", " green", " blue", " 5", " 3.2")
调用函数后输出:Array("\"Hello, everyone\"", "green", "blue", "5", "3.2"),完全符合预期。

如果后续需要处理单元格内的转义引号(比如"Hello ""World"""这种标准CSV转义格式),只需要在拼接完成后对字符串做一次转义替换即可,不需要修改核心逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 14:30:01