Spec-Zone.ru › D

std.csv

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

Значения, разделённые запятыми (CSV), обеспечивают простой способ передачи и хранения табличных данных. Программы часто используют свои собственные варианты формата CSV. Этот парсер будет приблизительно следовать RFC-4180. Входной CSV должен соответствовать следующим критериям (отличия от RFC-4180 в скобках):

  • Запись разделяется новой строкой (CRLF, LF, CR)
  • Конечная запись может заканчиваться новой строкой
  • Заголовок может быть предоставлен как первая запись во входных данных
  • Поля записи разделяются запятой (настраиваемо)
  • Поле, содержащее новые строки, запятые или двойные кавычки, должно быть заключено в двойные кавычки (настраиваемо)
  • Двойные кавычки в поле экранируются двойной кавычкой
  • Каждая запись должна содержать одинаковое количество полей

Пример
import std.algorithm;
import std.array;
import std.csv;
import std.stdio;
import std.typecons;

void main()
{
    auto text = "Joe,Carpenter,300000\nFred,Blacksmith,400000\r\n";

    foreach (record; csvReader!(Tuple!(string, string, int))(text))
    {
        writefln("%s works as a %s and earns $%d per year",
                 record[0], record[1], record[2]);
    }

    // To read the same string from the file "filename.csv":

    auto file = File("filename.csv", "r");
    foreach (record;
        file.byLine.joiner("\n").csvReader!(Tuple!(string, string, int)))
    {
        writefln("%s works as a %s and earns $%d per year",
                 record[0], record[1], record[2]);
    }
}
}
Когда входные данные содержат заголовок, Contents может быть указан как ассоциативный массив. Передача null означает, что заголовок присутствует.
auto text = "Name,Occupation,Salary\r"
    "Joe,Carpenter,300000\nFred,Blacksmith,400000\r\n";

foreach (record; csvReader!(string[string])
        (text, null))
{
    writefln("%s works as a %s and earns $%s per year.",
             record["Name"], record["Occupation"],
             record["Salary"]);
}

// To read the same string from the file "filename.csv":

auto file = File("filename.csv", "r");

foreach (record; csvReader!(string[string])
        (file.byLine.joiner("\n"), null))
{
    writefln("%s works as a %s and earns $%s per year.",
             record["Name"], record["Occupation"],
             record["Salary"]);
}
Этот модуль позволяет итерировать содержимое по записям, хранящимся в структуре, классе, ассоциативном массиве или как диапазон полей. При обнаружении ошибки выбрасывается CSVException (может быть отключено). csvNextToken сделано общедоступным, чтобы позволить попытку восстановления. Отключение исключений снимет многие ограничения, указанные выше. Кавычка может появиться в поле, если поле не было заключено в кавычки. Если в поле, заключённом в кавычки, есть кавычка сама по себе, не в конце поля, обработка этого поля завершится. Поле завершается, когда нет входных данных, даже если кавычка не была закрыта.
См. также:
Википедия Значения, разделённые запятыми
Лицензия:
Лицензия Boost 1.0.
Авторы:
Jesse Phillips
Источник
std/csv.d
класс CSVException: object.Exception;

Исключение, содержащее строку и столбец, при возникновении исключения.

Нумерация и строки, и столбцов начинается с единицы и соответствует местоположению в файле, а не любому указанному заголовку. Следует учитывать особые ситуации при отсутствии совпадения заголовка, см. HeaderMismatchException для получения подробностей.

При выполнении преобразований типов, std.conv.ConvException хранится в поле next.

Примеры:
import std.exception : collectException;
import std.algorithm.searching : count;
string text = "a,b,c\nHello,65";
auto ex = collectException!CSVException(csvReader(text).count);
// "(Row: 0, Col: 0) Row 2's length 2 does not match previous length of 3."
writeln(ex.toString);
Примеры:
import std.exception : collectException;
import std.algorithm.searching : count;
import std.typecons : Tuple;
string text = "a,b\nHello,65";
auto ex = collectException!CSVException(csvReader!(Tuple!(string,int))(text).count);
// "(Row: 1, Col: 2) Unexpected 'b' when converting from type string to type int"
writeln(ex.toString);
size_t строка;
size_t столбец;
класс IncompleteCellException: std.csv.CSVException;

Исключение, выбрасываемое, когда токен определяется как не завершён: в не заключённом в кавычки поле найдена кавычка, данные продолжаются после закрывающей кавычки или поле, заключённое в кавычки, не было закрыто до того, как данные опустели.

Примеры:
import std.exception : assertThrown;
string text = "a,\"b,c\nHello,65,2.5";
assertThrown!IncompleteCellException(text.csvReader(["a","b","c"]));
dstring неполныеДанные;

Данные, извлечённые из входных данных до обнаружения проблемы

Это поле заполняется при использовании csvReader, но не csvNextToken, так как эти данные уже были переданы в выходной диапазон.

класс ИсключениеНесоответствияЗаголовка: std.csv.CSVException;

Исключение, выбрасываемое в различных условиях в зависимости от типа Contents.

Структура, класс и ассоциативный массив

  • Когда заголовок предоставлен, но соответствующий столбец не найден


Другие
  • Когда заголовок предоставлен, но соответствующий столбец не найден
  • Порядок не совпал с тем, что найден в входе


Поскольку строка и столбец не имеют смысла, когда столбец, указанный заголовком, не найден в данных, и строка, и столбец будут равны нулю. В противном случае строка всегда равна единице, а столбец — первому найденному в заголовке экземпляру, который произошёл до предыдущего, начиная с единицы.

Примеры:
import std.exception : assertThrown;
string text = "a,b,c\nHello,65,2.5";
assertThrown!HeaderMismatchException(text.csvReader(["b","c","invalid"]));
перечисление Неправильный: int;

Определяет поведение при обнаружении ошибки.

Отключение исключений будет следовать этим правилам:

  • Кавычка может появиться в поле, если поле не было заключено в кавычки.
  • Если в поле, заключённом в кавычки, кавычка стоит сама по себе, не в конце поля, обработка этого поля завершится.
  • Поле завершается, когда нет входных данных, даже если кавычка не была закрыта.
  • Если предоставленный заголовок не соответствует порядку ввода, содержимое будет возвращено так, как оно было найдено во вводе.
  • Если заголовок содержит столбцы, которых нет во вводе, они будут проигнорированы.

Примеры:
import std.algorithm.comparison : equal;
import std.algorithm.searching : count;
import std.exception : assertThrown;

string text = "a,b,c\nHello,65,\"2.5";
assertThrown!IncompleteCellException(text.csvReader.count);

// ignore the exceptions and try to handle invalid CSV
auto firstLine = text.csvReader!(string, Malformed.ignore)(null).front;
assert(firstLine.equal(["Hello", "65", "2.5"]));
игнорировать

Исключения не выбрасываются из-за неправильного CSV.

выбрасыватьИсключение

Используйте исключения, когда входной CSV некорректен.

auto csvReader(Contents = string, Malformed ErrorLevel = Malformed.throwException, Range, Separator = char)(Range input, Separator delimiter = ',', Separator quote = '"')
Constraints: if (isInputRange!Range && is(immutable(ElementType!Range) == immutable(dchar)) && isSomeChar!Separator && !is(Contents T : T[U], U : string));

auto csvReader(Contents = string, Malformed ErrorLevel = Malformed.throwException, Range, Header, Separator = char)(Range input, Header header, Separator delimiter = ',', Separator quote = '"')
Constraints: if (isInputRange!Range && is(immutable(ElementType!Range) == immutable(dchar)) && isSomeChar!Separator && isForwardRange!Header && isSomeString!(ElementType!Header));

auto csvReader(Contents = string, Malformed ErrorLevel = Malformed.throwException, Range, Header, Separator = char)(Range input, Header header, Separator delimiter = ',', Separator quote = '"')
Constraints: if (isInputRange!Range && is(immutable(ElementType!Range) == immutable(dchar)) && isSomeChar!Separator && is(Header : typeof(null)));

Возвращает входной диапазон для итерации по записям, найденным в input.

Можно указать необязательный header. Первая запись будет считана как заголовок. Если Contents — структура, то ожидается, что предоставленный заголовок соответствует полям структуры. Когда Contents не является типом, который может содержать всю запись, header должен быть предоставлен в том же порядке, что и входные данные, иначе выбрасывается исключение.

Возвращает:
Входной диапазон R, как определено в std.range.primitives.isInputRange. Когда Contents является структурой, классом или ассоциативным массивом, тип элемента R — Contents, в противном случае тип элемента R — сам диапазон с типом элемента Contents. Если предоставлен аргумент header, возвращаемый диапазон предоставляет поле header для доступа к заголовку из входных данных в виде массива.
Выбрасывает:
CSVException Когда в не заключённом в кавычки поле найдена кавычка, данные продолжаются после закрывающей кавычки, поле, заключённое в кавычки, не было закрыто до того, как данные опустели, преобразование завершилось неудачей или длина строки не совпала с предыдущей длиной. HeaderMismatchException при предоставлении заголовка, но соответствующий столбец не найден или порядок не совпал с найденным во вводе. Прочитайте документацию по исключению для получения подробностей о том, когда исключение выбрасывается для различных типов Contents.
Примеры:
Можно указать Contents входных данных, если все записи имеют одинаковый тип, например, все целочисленные данные:
import std.algorithm.comparison : equal;
string text = "76,26,22";
auto records = text.csvReader!int;
assert(records.equal!equal([
    [76, 26, 22],
]));
Примеры:
Использование структуры с изменённым разделителем:
import std.algorithm.comparison : equal;
string text = "Hello;65;2.5\nWorld;123;7.5";
struct Layout
{
    string name;
    int value;
    double other;
}

auto records = text.csvReader!Layout(';');
assert(records.equal([
    Layout("Hello", 65, 2.5),
    Layout("World", 123, 7.5),
]));
Примеры:
Указание ErrorLevel как Malformed.ignore снимет ограничения на формат. Этот пример показывает, что исключение не выбрасывается при обнаружении кавычки в поле, не заключённом в кавычки.
string text = "A \" is now part of the data";
auto records = text.csvReader!(string, Malformed.ignore);
auto record = records.front;

writeln(record.front); // text
Примеры:
Чтение только столбца "b"
import std.algorithm.comparison : equal;
string text = "a,b,c\nHello,65,63.63\nWorld,123,3673.562";
auto records = text.csvReader!int(["b"]);

assert(records.equal!equal([
    [65],
    [123],
]));
Примеры:
Чтение с перестановкой столбцов, указав заголовок с другим порядком"
import std.algorithm.comparison : equal;
string text = "a,b,c\nHello,65,2.5\nWorld,123,7.5";
struct Layout
{
    int value;
    double other;
    string name;
}

auto records = text.csvReader!Layout(["b","c","a"]);
assert(records.equal([
    Layout(65, 2.5, "Hello"),
    Layout(123, 7.5, "World")
]));
Примеры:
Заголовок также может быть пустым, если входные данные содержат строку заголовка и все столбцы должны быть итерированы. Заголовок из входных данных всегда доступен из поля header.
string text = "a,b,c\nHello,65,63.63";
auto records = text.csvReader(null);

writeln(records.header); // ["a", "b", "c"]
void csvNextToken(Range, Malformed ErrorLevel = Malformed.throwException, Separator, Output)(ref Range input, ref Output ans, Separator sep, Separator quote, bool startQuoted = false)
Constraints: if (isSomeChar!Separator && isInputRange!Range && is(immutable(ElementType!Range) == immutable(dchar)) && isOutputRange!(Output, dchar));

Более низкий уровень управления парсингом CSV

Эта функция потребляет входные данные. После каждого вызова входные данные будут начинаться с разделителя или разделителя строк (\n, \r\n, \r), которые необходимо удалить для последующих вызовов.

Параметры:
Диапазон input Любой входной CSV
Выход ans Первое поле ввода
Разделитель sep Символ, представляющий запятую в спецификации
Разделитель quote Символ, представляющий кавычку в спецификации
bool startQuoted Указывает ли вход уже заключён в кавычки
Выбрасывает:
IncompleteCellException Когда в не заключённом в кавычки поле найдена кавычка, данные продолжаются после закрывающей кавычки или поле, заключённое в кавычки, не было закрыто до того, как данные опустели.
Примеры:
import std.array : appender;
import std.range.primitives : popFront;

string str = "65,63\n123,3673";

auto a = appender!(char[])();

csvNextToken(str,a,',','"');
writeln(a.data); // "65"
writeln(str); // ",63\n123,3673"

str.popFront();
a.shrinkTo(0);
csvNextToken(str,a,',','"');
writeln(a.data); // "63"
writeln(str); // "\n123,3673"

str.popFront();
a.shrinkTo(0);
csvNextToken(str,a,',','"');
writeln(a.data); // "123"
writeln(str); // ",3673"

© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_csv.html

Spec-Zone.ru

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