TinyCSV 1.0.1

TinyCSV 1.0.1

Darren Ford维护。



TinyCSV 1.0.1

  • Darren Ford

TinyCSV

TinyCSV是一个小程序Swift CSV解码器/编码器库,尽可能符合RFC 4180

tag Platform support License MIT Build

TinyCSV被设计为一个简洁的csv解码器和编码器,在解码时返回包含单元格(字符串)的基本数组。在解码时尝试尽可能地宽容,在编码时则非常严格。

TinyCSV解码不强制要求列、标题行或'预期'值。如果你的文件中的第一行有10个单元格,第二行只有8个单元格,那么返回的数据中就会这样。没有列格式化规则,您需要自己在返回数据之后处理和调整数据。TinyCSV试图根据(尽管定义得不够好)CSV规则将输入数据分割成行和单元格,然后让您决定在解析后对原始数据进行什么处理。

TinyCSV解码器期望以Swift String作为输入类型 - 如果你需要从文件中读取csv数据,你将不得不自己将文件读入一个String然后再传递给解码程序。

所有处理(目前)都是在内存中处理的,所以大型csv文件可能在小设备上对内存造成压力。如果你想要减少内存占用,你可能需要尝试查看事件驱动解码方法

解码支持

TinyCSV支持:

  • 定义分隔符(例如,逗号、分号、制表符)
  • 基本分隔符自动检测
  • 无引号字段(例如,cat, dog, bird
  • 引号字段(例如,"cat", "dog", "bird"
  • 混合引用(例如,"cat", dog, bird
  • 在引号字段内部嵌入引号,例如:"I like ""this""", "...but ""not"" this."
  • 在无引号字段内部使用字段转义字符嵌入门号(例如:I like ""this"", ...but ""not"" this.
  • 在引号字段内部嵌入换行符,例如:
    "鱼和"
    薯片,猫

    狗"
  • 在使用字段转义字符的无引号字段内部嵌入换行符,例如: 鱼和\
    薯片,猫\
    和\
  • 可选注释行
  • 可选忽略标题行

解析选项

指定分隔符

您可以在解码文件时指定使用的分隔符。

默认情况下,库通过扫描文件的第一行来尝试确定分隔符。如果无法确定分隔符,则将默认使用逗号。

// Use `tab` as a delimiter
let result = parser.decode(text: text, delimiter: .tab)

// Use `-` as the delimiter
let result = parser.decode(text: text, delimiter: "-")

跳过标题行

如果您的CSV文件开头有固定数量的非csv数据行,您可以通过设置标题行计数来跳过它们。

#Release 0.4
#Copyright (c) 2015 SomeCompany.
Z10,9,HFJ,,,,,,
B12,, IZOY, AB_K9Z_DD_18, RED,, 12,,,
let result = parser.decode(text: demoText, headerLineCount: 2)

行注释

您可以指定用于指示行要被视为注释的字符。如果行以注释字符开头,则该行将被忽略(除非它包含在多行引号字段中)。

例如

#Release 0.4
#Copyright (c) 2015 SomeCompany.
Z10,9,HFJ,,,,,,
B12,, IZOY, AB_K9Z_DD_18, RED,, 12,,,
// Use `#` to ignore the comment lines
let result = parser.decode(text: text, commentCharacter: "#")

字段转义字符

一些CSV使用转义字符来指示下一个字符应该是字面上的,特别是处理不引字段的数据文件时,例如:

…,Dr. Seltsam或我是如何学会热爱炸弹的(1964)…

解析器允许您可选地指定一个转义字符(在上面的示例中,转义字符是\),以表示嵌入的逗号是字段的一部分,不应被视为分隔符。

let result = parser.decode(text: text, fieldEscapeCharacter: "\\")

示例

解码

let parser = TinyCSV.Coder()

let text = /* some csv text */
let result = parser.decode(text: text)

let rowCount = result.records.count
let firstRowCellCount = result.records[0].count
let firstRowFirstCell = result.records[0][0]
let firstRowSecondCell = result.records[0][1]

编码

编码器会自动清理每个单元格的文本,这意味着您无需担心csv编码规则。

let parser = TinyCSV.Coder()

let cells = [["This \"cat\" is bonkers", "dog"], ["fish", "chips\nsalt"]]
let encoded = parser.encode(csvdata: cells)

生成

"This ""cat"" is bonkers","dog"
"fish","chips
salt"

事件驱动解码

TinyCSV在解析csv内容时内部使用事件驱动模型。

编码器的startDecoding方法允许您访问事件驱动解码功能,如果您需要更精细地控制解码过程,而不希望TinyCSV在内存中存储解码结果的完整副本。

您可以选择在以下情况下接收回调:

  • 解析器输出一个字段(包括行号、列号和文本)
  • 解析器输出一个记录(包括行号和列文本数组)

这些回调函数返回一个布尔值。返回true以继续解析,false以停止。

示例

let coder = TinyCSV.Coder()
coder.startDecoding(
   text: <some text>,
   emitField: { row, column, text in
      Swift.print("\(row), \(column): \(text)")
      return true
   },
   emitRecord: { row, columns in
      Swift.print("\(row): \(columns)")
      return true
   }
)

许可协议

MIT License

Copyright (c) 2023 Darren Ford

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.