Spec-Zone.ru › Nim

std/parsecsv

Source Edit

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

Основные принципы использования

import std/parsecsv
from std/os import paramStr
from std/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 std/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 и других операций обработки потоков (например, процедуры close)
  • модуль parseopt для парсера командной строки
  • модуль parsecfg для парсера файла конфигурации
  • модуль parsexml для парсера XML/HTML
  • модуль parsesql для парсера SQL
  • другие парсеры для других парсеров

Импорты

lexbase, streams, os

Типы

CsvError = object of IOError
Исключение, которое генерируется при возникновении ошибки парсинга. Source Edit
CsvParser = object of BaseLexer
  row*: CsvRow
  headers*: seq[string]

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

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

  • row — текущая строка
  • headers — столбцы, определённые в CSV-файле (читаются с помощью readHeaderRow). Используются с rowEntry.
Source Edit
CsvRow = seq[string]
Строка в CSV-файле. Source Edit

Процедуры

proc close(self: var CsvParser) {.inline, ...raises: [IOError, OSError],
                                  tags: [WriteIOEffect], forbids: [].}
Закрывает парсер self и связанный с ним входной поток. Source Edit
proc open(self: var CsvParser; filename: string; separator = ','; quote = '\"';
          escape = '\x00'; skipInitialSpace = false) {.
    ...raises: [CsvError, IOError, OSError], tags: [ReadIOEffect], forbids: [].}
Аналогично другой процедуре open, но создаёт для вас поток файла.

Пример:

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

См. также:

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

Пример:

import std/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()
Source Edit
proc processedRows(self: var CsvParser): int {.inline, ...raises: [], tags: [],
    forbids: [].}

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

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

Пример:

import std/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()
Source Edit
proc readHeaderRow(self: var CsvParser) {....raises: [IOError, OSError, CsvError],
    tags: [ReadIOEffect], forbids: [].}
Читает первую строку и создаёт таблицу поиска для номеров столбцов. См. также:
  • процедуру rowEntry

Пример:

import std/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()
Source Edit
proc readRow(self: var CsvParser; columns = 0): bool {.
    ...raises: [IOError, OSError, CsvError], tags: [ReadIOEffect], forbids: [].}

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

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

Пример:

import std/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()
Source Edit
proc rowEntry(self: var CsvParser; entry: string): var string {.
    ...raises: [KeyError], tags: [], forbids: [].}

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

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

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

Пример:

import std/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()
Source Edit

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

Spec-Zone.ru

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