一个微型的 Swift CSV 解码/编码库,尽可能地符合 RFC 4180 标准
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.
)"fish and
chips, cat
and
dog"
fish and\
chips, cat\
and\
dog
你可以指定在解码文件时使用的 delimiter。
默认情况下,该库尝试通过扫描文件中的第一行来确定 delimiter。 如果无法确定 delimiter,它将默认使用逗号。
// 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\, oder wie ich lernte\, die Bombe zu lieben (1964),…
解析器允许你选择性地指定一个转义字符(在上面的例子中,转义字符是 \
)来指示嵌入的逗号是字段的一部分,不应被视为 delimiter。
let result = parser.decode(text: text, fieldEscapeCharacter: "\\")
CSV 规范未指明如何处理在引用字段之外的字符,例如:-
"ABC" noodle, 123, "second"
默认情况下,CSV 解析器将忽略引用字符串之外的所有内容,因此在本例中, noodle
被丢弃。
let text = #""ABC" noodle, 123, "second""#
let parsed = parser.decode(text: text, delimiter: .comma)
// parsed.records = [["ABC", "123", "second"]]
设置 captureQuotedStringOverrunCharacters
,这些字符(直到下一个分隔符/eol/eof)将被添加到当前字段。
let text = #""ABC" noodle, 123, "second""#
let parsed = parser.decode(text: text, delimiter: .comma, captureQuotedStringOverrunCharacters: true)
// parsed.records = [["ABC noodle", "123", "second"]]
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 内容。
如果您需要更精细地控制解码过程,并且不希望 TinyCSV
在内存中存储解码结果的完整副本,则可以使用 coder 上的 startDecoding
方法来访问事件驱动解码功能。
您可以选择在以下情况下接收回调:-
这些回调函数返回一个布尔值。 返回 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) 2024 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.