Spec-Zone.ru › Nim 1

parsecsv

Этот модуль реализует простой высокопроизводительный парсер CSV (значений, разделённых запятыми).

Основные возможности

import parsecsv
from os import paramStr
from streams import newFileStream

var s = newFileStream(paramStr(1), fmRead)
if s == nil:
  quit("cannot open the file" & paramStr(1))

var x: CsvParser
open(x, s, paramStr(1))
while readRow(x):
  echo "new row: "
  for val in items(x.row):
    echo "##", val, "##"
close(x)

Для CSV-файлов с заголовком, заголовок можно прочитать и использовать его как ссылку для доступа к элементам с помощью rowEntry:

import parsecsv

# Prepare a file
let content = """One,Two,Three,Four
1,2,3,4
10,20,30,40
100,200,300,400
"""
writeFile("temp.csv", content)

var p: CsvParser
p.open("temp.csv")
p.readHeaderRow()
while p.readRow():
  echo "new row: "
  for col in items(p.headers):
    echo "##", col, ":", p.rowEntry(col), "##"
p.close()

См. также

  • модуль streams для использования open proc и других операций обработки потоков (например, close proc)
  • модуль parseopt для парсера командной строки
  • модуль parsecfg для парсера конфигурационных файлов
  • модуль parsexml для парсера XML/HTML
  • модуль parsesql для парсера SQL
  • другие парсеры для других парсеров

Импорты

lexbase, streams, os

Типы

CsvRow = seq[string]
Строка в CSV-файле. Исходный код Редактировать
CsvParser = object of BaseLexer
  row*: CsvRow
  filename: string
  sep, quote, esc: char
  skipWhite: bool
  currRow: int
  headers*: seq[string]

Объект парсера.

Он состоит из двух публичных полей:

  • row — текущая строка
  • headers — столбцы, определённые в CSV-файле (считываются с помощью readHeaderRow). Используются с rowEntry.
Исходный код Редактировать
CsvError = object of IOError
Исключение, которое генерируется при ошибке парсинга. Исходный код Редактировать

Процедуры

proc open(my: var CsvParser; input: Stream; filename: string; separator = ',';
          quote = '\"'; escape = '\x00'; skipInitialSpace = false) {...}{.
    raises: [IOError, OSError], tags: [ReadIOEffect].}
Инициализирует парсер с входным потоком. Filename используется только для красивых сообщений об ошибках. Поведение парсера можно контролировать с помощью различных необязательных параметров:
  • separator: символ, используемый для разделения полей
  • quote: используется для цитирования полей, содержащих специальные символы, такие как separator, quote или символы новой строки. '\0' отключает парсинг кавычек.
  • escape: удаляет любое специальное значение из следующего символа; '\0' отключает экранирование; если экранирование отключено и quote не '\0', две quote символа разбираются как один буквальный quote символ.
  • skipInitialSpace: Если true, пробелы, непосредственно следующие за separator игнорируются.

См. также:

  • процедуру open, которая создаёт поток файла для вас

Пример:

import streams
var strm = newStringStream("One,Two,Three\n1,2,3\n10,20,30")
var parser: CsvParser
parser.open(strm, "tmp.csv")
parser.close()
strm.close()
Исходный код Редактировать
proc open(my: var CsvParser; filename: string; separator = ','; quote = '\"';
          escape = '\x00'; skipInitialSpace = false) {...}{.
    raises: [CsvError, IOError, OSError], tags: [ReadIOEffect].}
Аналогично другой процедуре open, но создаёт для вас поток файла.

Пример:

from os import removeFile
writeFile("tmp.csv", "One,Two,Three\n1,2,3\n10,20,300")
var parser: CsvParser
parser.open("tmp.csv")
parser.close()
removeFile("tmp.csv")
Исходный код Редактировать
proc processedRows(my: var CsvParser): int {...}{.raises: [], tags: [].}

Возвращает количество обработанных строк.

Но даже если readRow достиг EOF, счётчик обработанных строк увеличивается.

Пример:

import streams

var strm = newStringStream("One,Two,Three\n1,2,3")
var parser: CsvParser
parser.open(strm, "tmp.csv")
doAssert parser.readRow()
doAssert parser.processedRows() == 1
doAssert parser.readRow()
doAssert parser.processedRows() == 2
## Even if `readRow` arrived at EOF then `processedRows` is incremented.
doAssert parser.readRow() == false
doAssert parser.processedRows() == 3
doAssert parser.readRow() == false
doAssert parser.processedRows() == 4
parser.close()
strm.close()
Исходный код Редактировать
proc readRow(my: var CsvParser; columns = 0): bool {...}{.
    raises: [IOError, OSError, CsvError], tags: [ReadIOEffect].}

Считывает следующую строку; если columns > 0, она ожидает, что строка будет содержать ровно столько столбцов. Возвращает false, если достигнут конец файла, иначе true.

Пустые строки пропускаются.

Пример:

import streams
var strm = newStringStream("One,Two,Three\n1,2,3\n\n10,20,30")
var parser: CsvParser
parser.open(strm, "tmp.csv")
doAssert parser.readRow()
doAssert parser.row == @["One", "Two", "Three"]
doAssert parser.readRow()
doAssert parser.row == @["1", "2", "3"]
## Blank lines are skipped.
doAssert parser.readRow()
doAssert parser.row == @["10", "20", "30"]

var emptySeq: seq[string]
doAssert parser.readRow() == false
doAssert parser.row == emptySeq
doAssert parser.readRow() == false
doAssert parser.row == emptySeq

parser.close()
strm.close()
Исходный код Редактировать
proc close(my: var CsvParser) {...}{.inline, raises: [Exception, IOError, OSError],
                                tags: [WriteIOEffect].}
Закрывает парсер my и связанный с ним входной поток. Исходный код Редактировать
proc readHeaderRow(my: var CsvParser) {...}{.raises: [IOError, OSError, CsvError],
                                        tags: [ReadIOEffect].}
Считывает первую строку и создаёт таблицу поиска для номеров столбцов. См. также:
  • процедуру rowEntry

Пример:

import streams

var strm = newStringStream("One,Two,Three\n1,2,3")
var parser: CsvParser
parser.open(strm, "tmp.csv")

parser.readHeaderRow()
doAssert parser.headers == @["One", "Two", "Three"]
doAssert parser.row == @["One", "Two", "Three"]

doAssert parser.readRow()
doAssert parser.headers == @["One", "Two", "Three"]
doAssert parser.row == @["1", "2", "3"]

parser.close()
strm.close()
Исходный код Редактировать
proc rowEntry(my: var CsvParser; entry: string): var string {...}{.
    raises: [KeyError], tags: [].}

Доступ к указанному entry текущей строки.

Предполагается, что readHeaderRow уже была вызвана.

Если указанный entry не существует, генерируется KeyError.

Пример:

import streams
var strm = newStringStream("One,Two,Three\n1,2,3\n\n10,20,30")
var parser: CsvParser
parser.open(strm, "tmp.csv")
## Requires calling `readHeaderRow`.
parser.readHeaderRow()
doAssert parser.readRow()
doAssert parser.rowEntry("One") == "1"
doAssert parser.rowEntry("Two") == "2"
doAssert parser.rowEntry("Three") == "3"
doAssertRaises(KeyError):
  discard parser.rowEntry("NonexistentEntry")
parser.close()
strm.close()
Исходный код Редактировать

© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/parsecsv.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API