Spec-Zone.ru › Ruby 2.6

класс CSV

Родитель:
Объект
Включенные модули:
Enumerable

Этот класс предоставляет полный интерфейс к файлам и данным CSV. Он предлагает инструменты для чтения и записи в строки или объекты IO по мере необходимости.

Наиболее общий интерфейс библиотеки:

csv = CSV.new(string_or_io, **options)

# Reading: IO object should be open for read
csv.read # => array of rows
# or
csv.each do |row|
  # ...
end
# or
row = csv.shift

# Writing: IO object should be open for write
csv << row

Существует несколько специализированных методов класса для однострочного чтения или записи, описанных в разделе «Специализированные методы».

Если в ::new передается String, он внутри обертывается в объект StringIO.

options может использоваться для указания конкретного формата CSV (разделители столбцов, разделители строк, кавычки значений и т. д.), а также для преобразования данных, см. раздел «Преобразование» для описания последнего.

Специализированные методы

Чтение

# From a file: all at once
arr_of_rows = CSV.read("path/to/file.csv", **options)
# iterator-style:
CSV.foreach("path/to/file.csv", **options) do |row|
  # ...
end

# From a string
arr_of_rows = CSV.parse("CSV,data,String", **options)
# or
CSV.parse("CSV,data,String", **options) do |row|
  # ...
end

Запись

# To a file
CSV.open("path/to/file.csv", "wb") do |csv|
  csv << ["row", "of", "CSV", "data"]
  csv << ["another", "row"]
  # ...
end

# To a String
csv_string = CSV.generate do |csv|
  csv << ["row", "of", "CSV", "data"]
  csv << ["another", "row"]
  # ...
end

Сокращения

# Core extensions for converting one line
csv_string = ["CSV", "data"].to_csv   # to CSV
csv_array  = "CSV,String".parse_csv   # from CSV

# CSV() method
CSV             { |csv_out| csv_out << %w{my data here} }  # to $stdout
CSV(csv = "")   { |csv_str| csv_str << %w{my data here} }  # to a String
CSV($stderr)    { |csv_err| csv_err << %w{my data here} }  # to $stderr
CSV($stdin)     { |csv_in|  csv_in.each { |row| p row } }  # from $stdin

Преобразование

CSV с заголовками

CSV позволяет указать имена столбцов файла CSV, находятся ли они в данных или предоставляются отдельно. Если заголовки указаны, методы чтения возвращают экземпляр CSV::Table, состоящий из CSV::Row.

# Headers are part of data
data = CSV.parse(<<~ROWS, headers: true)
  Name,Department,Salary
  Bob,Engineering,1000
  Jane,Sales,2000
  John,Management,5000
ROWS

data.class      #=> CSV::Table
data.first      #=> #<CSV::Row "Name":"Bob" "Department":"Engineering" "Salary":"1000">
data.first.to_h #=> {"Name"=>"Bob", "Department"=>"Engineering", "Salary"=>"1000"}

# Headers provided by developer
data = CSV.parse('Bob,Engeneering,1000', headers: %i[name department salary])
data.first      #=> #<CSV::Row name:"Bob" department:"Engineering" salary:"1000">

Чтение данных с типами

CSV позволяет предоставить набор преобразователей данных, например, преобразования для применения к входным данным. Преобразователь может быть символом из ключей константы CSV::Converters или лямбдой.

# Without any converters:
CSV.parse('Bob,2018-03-01,100')
#=> [["Bob", "2018-03-01", "100"]]

# With built-in converters:
CSV.parse('Bob,2018-03-01,100', converters: %i[numeric date])
#=> [["Bob", #<Date: 2018-03-01>, 100]]

# With custom converters:
CSV.parse('Bob,2018-03-01,100', converters: [->(v) { Time.parse(v) rescue v }])
#=> [["Bob", 2018-03-01 00:00:00 +0200, "100"]]

CSV и кодировки символов (M17n или многоязычие)

Этот новый анализатор CSV поддерживает многоязычие. Парсер работает в кодировке Encoding объекта IO или String, который читается или записывается. Ваши данные никогда не транскодируются (если вы не попросите Ruby их транскодировать) и буквально будут проанализированы в Encoding, в котором они находятся. Таким образом, CSV вернет массивы или строки строк в Encoding ваших данных. Это достигается путем транскодирования самого парсера в вашу Encoding.

Некоторое транскодирование, конечно, должно произойти, чтобы обеспечить поддержку многократной кодировки. Например, :col_sep, :row_sep, и :quote_char должны быть транскодированы для соответствия вашим данным. Надеюсь, это сделает весь процесс прозрачным, поскольку значения по умолчанию CSV должны просто автоматически работать с вашими данными. Однако вы можете вручную задать эти значения в целевой Encoding, чтобы избежать преобразования.

Также важно отметить, что, хотя весь основной парсер CSV теперь не зависит от Encoding, некоторые функции не зависят от него. Например, встроенные преобразователи попытаются транскодировать данные в UTF-8 перед выполнением преобразований. Опять же, вы можете предоставить пользовательские преобразователи, которые знают о ваших кодировках, чтобы избежать этого преобразования. Мне слишком сложно поддерживать родные преобразования во всех кодировках Ruby.

В любом случае, практический аспект этого прост: убедитесь, что объекты IO и String, переданные в CSV, имеют установленную правильную Encoding, и все должно работать. Методы CSV, которые позволяют вам открывать объекты IO (CSV::foreach(), CSV::open(), CSV::read() и CSV::readlines()), позволяют вам указать Encoding.

Одно небольшое исключение возникает при генерации CSV в String с Encoding, которая несовместима с ASCII. Для CSV нет существующих данных, которые можно было бы использовать для подготовки, и поэтому, скорее всего, вам нужно будет вручную указать необходимую Encoding для большинства таких случаев. Однако при использовании CSV::generate_line() или Array#to_csv() он попытается угадать, используя поля в строке вывода.

Я стараюсь указывать любые другие проблемы с Encoding в документации методов по мере их появления.

Это было протестировано по мере моих возможностей со всеми кодировками, кроме «фиктивных», которые поставляются с Ruby. Однако это новый и смелый код, и в нем могут быть ошибки. Пожалуйста, сообщите о любых найденных проблемах по адресу электронной почты.

END_OF_DOCUMENT_MARKER

Константы

ConverterEncoding

Кодировка, используемая всеми преобразователями.

Converters

Этот Hash содержит встроенные преобразователи CSV, к которым можно получить доступ по имени. Вы можете выбрать Converters с помощью CSV.convert() или через options Hash, переданный в CSV::new().

:integer

Преобразует любой поле, который принимает Integer().

:float

Преобразует любое поле, которое принимает Float().

:numeric

Сочетание :integer и :float.

:date

Преобразует любое поле, которое принимает Date::parse().

:date_time

Преобразует любое поле, которое принимает DateTime::parse().

:all

Все встроенные преобразователи. Сочетание :date_time и :numeric.

Все встроенные преобразователи кодируют данные поля в UTF-8 перед выполнением преобразования. Если данные не могут быть закодированы в UTF-8, преобразование завершится с ошибкой, а поле останется без изменений.

Этот Hash намеренно не заморожен, и пользователи могут добавлять в него значения, к которым могут получить доступ все объекты CSV.

Для добавления комбинированного поля значение должно быть Array имён. Комбинированные поля могут быть вложены в другие комбинированные поля.

DEFAULT_OPTIONS

Параметры, используемые, когда вызывающий код не предоставляет альтернатив. Они следующие:

:col_sep

","

:row_sep

:auto

:quote_char

'"'

:field_size_limit

nil

:converters

nil

:unconverted_fields

nil

:headers

false

:return_headers

false

:header_converters

nil

:skip_blanks

false

:force_quotes

false

:skip_lines

nil

:liberal_parsing

false

:quote_empty

true

DateMatcher

Регулярное выражение, используемое для поиска и преобразования некоторых распространённых форматов Date.

DateTimeMatcher

Регулярное выражение, используемое для поиска и преобразования некоторых распространённых форматов DateTime.

FieldInfo

Структура FieldInfo содержит подробности о позиции поля в источнике данных, из которого оно было прочитано. CSV передаст эту структуру Struct некоторым блокам, которые принимают решения, основанные на структуре поля. Смотрите пример в CSV.convert_fields().

index

Индекс поля в строке (с нуля).

line

Строка источника данных, из которой взята эта строка.

header

Заголовок столбца, если он доступен.

HeaderConverters

Этот Hash содержит встроенные преобразователи заголовков CSV, к которым можно получить доступ по имени. Вы можете выбрать HeaderConverters с помощью CSV.header_convert() или через options Hash, переданный в CSV::new().

:downcase

Вызывает downcase() для заголовка String.

:symbol

Удаляются начальные и конечные пробелы, строка приводится к нижнему регистру, оставшиеся пробелы заменяются на подчеркивания, небуквенные символы удаляются, а затем вызывается to_sym().

Все встроенные преобразователи заголовков кодируют данные заголовков в UTF-8 перед выполнением преобразования. Если данные не могут быть закодированы в UTF-8, преобразование завершится с ошибкой, а заголовок останется без изменений.

Этот Hash намеренно не заморожен, и пользователи могут добавлять в него значения, к которым могут получить доступ все объекты CSV.

Для добавления комбинированного поля значение должно быть Array имён. Комбинированные поля могут быть вложены в другие комбинированные поля.

VERSION

Версия установленной библиотеки.

Атрибуты

encoding[R]

Кодировка Encoding, в которой CSV выполняет чтение или запись. Это кодировка Encoding, в которой будут получены прочитанные данные, и/или Encoding кодировка, в которой данные будут записаны.

Методы публичного класса

filter( **options ) { |row| ... } Показать исходный код
filter( input, **options ) { |row| ... }
filter( input, output, **options ) { |row| ... }
# File lib/csv.rb, line 468
def self.filter(input=nil, output=nil, **options)
  # parse options for input, output, or both
  in_options, out_options = Hash.new, {row_sep: $INPUT_RECORD_SEPARATOR}
  options.each do |key, value|
    case key.to_s
    when /\Ain(?:put)?_(.+)\Z/
      in_options[$1.to_sym] = value
    when /\Aout(?:put)?_(.+)\Z/
      out_options[$1.to_sym] = value
    else
      in_options[key]  = value
      out_options[key] = value
    end
  end
  # build input and output wrappers
  input  = new(input  || ARGF,    in_options)
  output = new(output || $stdout, out_options)

  # read, yield, write
  input.each do |row|
    yield row
    output << row
  end
end

Этот метод — удобный инструмент для создания фильтров в стиле Unix для CSV данных. Каждая строка передаётся предоставленному блоку, который может её изменить по мере необходимости. После возврата из блока строка добавляется к output — изменённая или нет.

Аргументы input и output могут быть любыми, что CSV::new() принимает (обычно объекты String или IO). Если не указаны, они по умолчанию равны ARGF и $stdout.

Параметр options также фильтруется до CSV::new() после некоторого хитрого разбора ключей. Любой ключ, начинающийся с :in_ или :input_, будет иметь этот префикс удалён и будет использоваться только в options Hash для объекта input. Ключи, начинающиеся с :out_ или :output_, влияют только на output. Все остальные ключи присваиваются обоим объектам.

Параметр :output_row_sep option по умолчанию равен $INPUT_RECORD_SEPARATOR ($/).

foreach(path, mode="r", **options, &block) Показать исходный код
# File lib/csv.rb, line 507
def self.foreach(path, mode="r", **options, &block)
  return to_enum(__method__, path, mode, options) unless block_given?
  open(path, mode, options) do |csv|
    csv.each(&block)
  end
end

Этот метод предназначен как основной интерфейс для чтения файлов CSV. Вы передаёте path и любые options для настройки чтения. Каждая строка файла по очереди передаётся предоставленному block.

Параметр options может быть любым, что CSV::new() понимает. Этот метод также понимает дополнительный параметр :encoding, который можно использовать для указания Encoding данных в файле, подлежащем чтению. Его необходимо указать, если ваши данные не в формате Encoding::default_external(). CSV будет использовать его для определения способа анализа данных. Можно предоставить второй Encoding для транскодирования данных во время чтения. Например, encoding: "UTF-32BE:UTF-8" будет читать данные UTF-32BE из файла, но транскодировать их в UTF-8 перед тем, как CSV их проанализирует.

generate( str, **options ) { |csv| ... } Показать исходный код
generate( **options ) { |csv| ... }
# File lib/csv.rb, line 532
def self.generate(str=nil, **options)
  # add a default empty String, if none was given
  if str
    str = StringIO.new(str)
    str.seek(0, IO::SEEK_END)
  else
    encoding = options[:encoding]
    str = +""
    str.force_encoding(encoding) if encoding
  end
  csv = new(str, options) # wrap
  yield csv         # yield for appending
  csv.string        # return final String
end

Этот метод оборачивает предоставленную вами строку String или пустую строку по умолчанию String в объект CSV, который передаётся предоставленному блоку. Вы можете использовать блок для добавления строк CSV в String, и по завершении блока будет возвращена итоговая String.

Обратите внимание, что переданная String изменяется этим методом. Вызовите dup() перед передачей, если вам нужна новая String.

Параметр options может быть любым, что CSV::new() понимает. Этот метод понимает дополнительный параметр :encoding, когда не передаётся String, для установки базового Encoding для вывода. CSV нуждается в этой подсказке, если вы планируете выводить несовместимые с ASCII данные.

generate_line(row, **options) Показать исходный код
# File lib/csv.rb, line 560
def self.generate_line(row, **options)
  options = {row_sep: $INPUT_RECORD_SEPARATOR}.merge(options)
  str = +""
  if options[:encoding]
    str.force_encoding(options[:encoding])
  elsif field = row.find {|f| f.is_a?(String)}
    str.force_encoding(field.encoding)
  end
  (new(str, options) << row).string
end

Этот метод — сокращённая запись для преобразования одной строки (массива) в CSV String.

Параметр options может быть любым, что CSV::new() понимает. Этот метод понимает дополнительный параметр :encoding, чтобы установить базовый Encoding для вывода. Этот метод попытается угадать ваш Encoding из первого не-nil поля в row, если это возможно, но вам может потребоваться использовать этот параметр как резервный вариант.

Параметр :row_sep option по умолчанию равен $INPUT_RECORD_SEPARATOR ($/).

instance(data = $stdout, **options) { |instance| ... } Показать исходный код
# File lib/csv.rb, line 428
def self.instance(data = $stdout, **options)
  # create a _signature_ for this method call, data object and options
  sig = [data.object_id] +
        options.values_at(*DEFAULT_OPTIONS.keys.sort_by { |sym| sym.to_s })

  # fetch or create the instance for this signature
  @@instances ||= Hash.new
  instance = (@@instances[sig] ||= new(data, options))

  if block_given?
    yield instance  # run block, if given, returning result
  else
    instance        # or return the instance
  end
end

Этот метод вернёт экземпляр CSV, как и CSV::new(), но экземпляр будет кэширован и возвращён для всех последующих вызовов этого метода для того же объекта data (проверяется с помощью Object#object_id()) с теми же options.

Если блок задан, экземпляр передаётся в блок, и возвращаемое значение становится возвращаемым значением блока.

END_OF_DOCUMENT_MARKER
new(data, col_sep: ",", row_sep: :auto, quote_char: '"', field_size_limit: nil, converters: nil, unconverted_fields: nil, headers: false, return_headers: false, write_headers: nil, header_converters: nil, skip_blanks: false, force_quotes: false, skip_lines: nil, liberal_parsing: false, internal_encoding: nil, external_encoding: nil, encoding: nil, nil_value: nil, empty_value: "", quote_empty: true, write_converters: nil, write_nil_value: nil, write_empty_value: "", strip: false) Показать исходный код
# File lib/csv.rb, line 898
def initialize(data,
               col_sep: ",",
               row_sep: :auto,
               quote_char: '"',
               field_size_limit: nil,
               converters: nil,
               unconverted_fields: nil,
               headers: false,
               return_headers: false,
               write_headers: nil,
               header_converters: nil,
               skip_blanks: false,
               force_quotes: false,
               skip_lines: nil,
               liberal_parsing: false,
               internal_encoding: nil,
               external_encoding: nil,
               encoding: nil,
               nil_value: nil,
               empty_value: "",
               quote_empty: true,
               write_converters: nil,
               write_nil_value: nil,
               write_empty_value: "",
               strip: false)
  raise ArgumentError.new("Cannot parse nil as CSV") if data.nil?

  # create the IO object we will read from
  @io = data.is_a?(String) ? StringIO.new(data) : data
  @encoding = determine_encoding(encoding, internal_encoding)

  @base_fields_converter_options = {
    nil_value: nil_value,
    empty_value: empty_value,
  }
  @write_fields_converter_options = {
    nil_value: write_nil_value,
    empty_value: write_empty_value,
  }
  @initial_converters = converters
  @initial_header_converters = header_converters
  @initial_write_converters = write_converters

  @parser_options = {
    column_separator: col_sep,
    row_separator: row_sep,
    quote_character: quote_char,
    field_size_limit: field_size_limit,
    unconverted_fields: unconverted_fields,
    headers: headers,
    return_headers: return_headers,
    skip_blanks: skip_blanks,
    skip_lines: skip_lines,
    liberal_parsing: liberal_parsing,
    encoding: @encoding,
    nil_value: nil_value,
    empty_value: empty_value,
    strip: strip,
  }
  @parser = nil

  @writer_options = {
    encoding: @encoding,
    force_encoding: (not encoding.nil?),
    force_quotes: force_quotes,
    headers: headers,
    write_headers: write_headers,
    column_separator: col_sep,
    row_separator: row_sep,
    quote_character: quote_char,
    quote_empty: quote_empty,
  }

  @writer = nil
  writer if @writer_options[:write_headers]
end

Этот конструктор будет оборачивать объект типа String или IO, переданный data для чтения и/или записи. В дополнение к методам экземпляра CSV, делегируются некоторые методы IO. (См. CSV::open() для полного списка.) Если вы передаёте String для data, вы можете позже извлечь его (например, после записи в него) с помощью CSV.string().

Обратите внимание, что обернутый String будет расположен в начале (для чтения). Если вы хотите расположить его в конце (для записи), используйте CSV::generate(). Если вам нужно другое позиционирование, передайте вместо этого предварительно заданный объект StringIO.

Вы можете установить любые предпочтения для чтения и/или записи в options Hash. Доступные параметры:

:col_sep

Строка String, помещаемая между каждым полем. Эта строка String будет преобразована в кодировку данных Encoding перед разбором.

:row_sep

Строка String, добавляемая в конец каждой строки. Это может быть установлено в специальное значение :auto, которое запрашивает, чтобы CSV автоматически обнаружил его по данным. Автоматическое обнаружение считывает данные в поисках следующей последовательности "\r\n", "\n", или "\r". Последовательность будет выбрана, даже если она встречается в цитируемом поле, исходя из предположения, что у вас будут одинаковые символы конца строки. Если ни одна из этих последовательностей не найдена, data устанавливается в ARGF, STDIN, STDOUT, или STDERR, или поток доступен только для вывода, используется значение по умолчанию $INPUT_RECORD_SEPARATOR ($/). Очевидно, что обнаружение занимает некоторое время. Set вручную, если скорость важна. Также обратите внимание, что объекты IO на Windows должны быть открыты в двоичном режиме, если эта функция будет использоваться, поскольку перевод символов конца строки может вызвать проблемы с переустановкой позиции документа в то место, где она была до предварительного чтения. Эта строка String будет преобразована в кодировку данных Encoding перед разбором.

:quote_char

Символ, используемый для цитирования полей. Это должен быть одиночный символьный String. Это полезно для приложений, которые неправильно используют ' в качестве символа цитирования вместо правильного ". CSV всегда будет рассматривать двойную последовательность этого символа как экранированный символ цитирования. Эта строка String будет преобразована в кодировку данных Encoding перед разбором.

:field_size_limit

Это максимальный размер, до которого CSV будет читать вперёд в поисках закрывающего кавычки для поля. (На самом деле, он читает до первой позиции конца строки за пределами этого размера.) Если кавычки не найдены в пределах предела, CSV сгенерирует исключение MalformedCSVError, предполагая, что данные неверные. Вы можете использовать этот предел, чтобы предотвратить то, что по сути является DoS-атакой на анализатор. Однако этот предел может привести к тому, что законный разбор завершится неудачей, поэтому по умолчанию он установлен на nil, или выключен.

:converters

Массив имён из Converters Hash и/или лямбда-выражений, которые обрабатывают пользовательское преобразование. Один преобразователь не обязательно должен быть в массиве. Все встроенные преобразователи пытаются преобразовать поля в UTF-8 перед преобразованием. Преобразование завершится неудачей, если данные не могут быть преобразованы, оставив поле неизменённым.

:unconverted_fields

Если установлено значение true, будет добавлен метод unconverted_fields(), который будет возвращать поля в виде, в котором они были до преобразования для всех возвращаемых строк (массива или CSV::Row). Обратите внимание, что :headers, предоставленный Array или String, не являлись полями документа и, следовательно, имеют прикреплённый пустой массив.

:headers

Если установлено значение :first_row или true, первая строка файла CSV будет рассматриваться как строка заголовков. Если установлено значение массива, его содержимое будет использоваться как заголовки. Если установлено значение строки, строка заголовков обрабатывается вызовом CSV::parse_line() с теми же :col_sep, :row_sep, и :quote_char, что и этот экземпляр, чтобы получить массив заголовков. Это значение заставляет CSV#shift() возвращать строки в виде объектов CSV::Row, а CSV#read() - объекты CSV::Table вместо массива массивов.

:return_headers

При false, строки заголовков игнорируются. Если установлено значение true, строки заголовков возвращаются в объекте CSV::Row с идентичными заголовками и полями (за исключением того, что поля не проходят через преобразователи).

:write_headers

При true и :headers, в выходной файл будет добавлена строка заголовков.

:header_converters

Функционально идентично :converters, за исключением того, что преобразования применяются только к строкам заголовков. Все встроенные преобразователи пытаются преобразовать заголовки в UTF-8 перед преобразованием. Преобразование завершится неудачей, если данные не могут быть преобразованы, оставив заголовок неизменённым.

:skip_blanks

Если установлено значение true, CSV пропустит пустые строки. Обратите внимание, что это значение не будет пропускать строки, содержащие разделители столбцов, даже если в строках нет фактических данных. Если вы хотите пропустить строки, содержащие разделители, но не содержащие содержимого, воспользуйтесь :skip_lines, или проверьте, пуст ли результат compact.empty? для каждого поля в строке.

:force_quotes

Если установлено значение true, CSV будет заключать все CSV поля, которые он создаёт.

:skip_lines

При установке объекта, отвечающего за match, все строки, соответствующие ей, считаются комментариями и игнорируются во время разбора. При установке строки, она сначала преобразуется в Regexp. При установке значения nil ни одна строка не считается комментарием. Если переданный объект не отвечает за match, выбрасывается ArgumentError.

:liberal_parsing

При установке значения true, CSV попытается разобрать входные данные, не соответствующие RFC 4180, например, двойные кавычки в нецитируемых полях.

:nil_value

При установке объекта любые значения пустых полей заменяются на установленный объект, а не на nil.

:empty_value

При установке объекта, любые значения пустой строковой поля заменяются на установленный объект.

:quote_empty

TODO

:write_converters

TODO

:write_nil_value

TODO

:write_empty_value

TODO

:strip

TODO

См. CSV::DEFAULT_OPTIONS для значений по умолчанию.

Параметры нельзя переопределить в методах экземпляров по причинам производительности, поэтому убедитесь, что вы установили желаемые значения здесь.

open( filename, mode = "rb", **options ) { |faster_csv| ... } Показать исходный код
open( filename, **options ) { |faster_csv| ... }
open( filename, mode = "rb", **options )
open( filename, **options )
# File lib/csv.rb, line 634
def self.open(filename, mode="r", **options)
  # wrap a File opened with the remaining +args+ with no newline
  # decorator
  file_opts = {universal_newline: false}.merge(options)

  begin
    f = File.open(filename, mode, file_opts)
  rescue ArgumentError => e
    raise unless /needs binmode/.match?(e.message) and mode == "r"
    mode = "rb"
    file_opts = {encoding: Encoding.default_external}.merge(file_opts)
    retry
  end
  begin
    csv = new(f, options)
  rescue Exception
    f.close
    raise
  end

  # handle blocks like Ruby's open(), not like the CSV library
  if block_given?
    begin
      yield csv
    ensure
      csv.close
    end
  else
    csv
  end
end

Этот метод открывает объект IO и оборачивает его с помощью CSV. Он предназначен в качестве основного интерфейса для записи файла CSV.

Вы должны передать filename, и можете дополнительно указать mode для функции open() Ruby. Вы также можете передать необязательный Hash содержащий любые options параметры, которые понимает CSV::new() в качестве последнего аргумента.

Этот метод работает аналогично вызову open() в Ruby, в том смысле, что он передаёт объект CSV в предоставленный блок и закрывает его по завершении блока, или возвращает объект CSV при отсутствии блока. (Примечание: Это отличается от библиотеки Ruby 1.8 CSV, которая передавала строки в блок. Используйте CSV::foreach() для такого поведения.)

Вы должны указать mode с указанием кодировки Encoding, если ваши данные не в кодировке Encoding::default_external(). CSV будет проверять кодировку Encoding базового объекта IO (установленной передаваемым вами mode) для определения способа обработки данных. Вы можете указать вторую кодировку Encoding для преобразования данных при чтении, так же как и при обычном вызове IO::open(). Например, "rb:UTF-32BE:UTF-8" будет читать данные UTF-32BE из файла, но преобразовывать их в UTF-8 до того, как CSV их обработает.

Открытый объект CSV делегирует многие методы объекта IO для удобства. Вы можете вызвать:

  • binmode()

  • binmode?()

  • close()

  • close_read()

  • close_write()

  • closed?()

  • eof()

  • eof?()

  • external_encoding()

  • fcntl()

  • fileno()

  • flock()

  • flush()

  • fsync()

  • internal_encoding()

  • ioctl()

  • isatty()

  • path()

  • pid()

  • pos()

  • pos=()

  • reopen()

  • seek()

  • stat()

  • sync()

  • sync=()

  • tell()

  • to_i()

  • to_io()

  • truncate()

  • tty?()

parse( str, **options ) { |row| ... } Показать исходный код
parse( str, **options )
# File lib/csv.rb, line 678
def self.parse(*args, &block)
  csv = new(*args)

  return csv.each(&block) if block_given?

  # slurp contents, if no block is given
  begin
    csv.read
  ensure
    csv.close
  end
end

Этот метод может использоваться для простого парсинга CSV из String. Вы можете предоставить block, которое будет вызываться с каждой строкой String по очереди, или просто использовать возвращённый массив Array массивов (если block не указан).

Вы передаёте str для чтения и необязательный options содержащий любые параметры, которые понимает CSV::new().

parse_line(line, **options) Показать исходный код
# File lib/csv.rb, line 698
def self.parse_line(line, **options)
  new(line, options).shift
end

Этот метод является сокращением для преобразования одной строки CSV String в массив Array. Обратите внимание, что если line содержит несколько строк, всё, что находится за первой строкой, игнорируется.

Параметр options может быть любым, что понимает CSV::new().

read(path, *options) Показать исходный код
# File lib/csv.rb, line 713
def self.read(path, *options)
  open(path, *options) { |csv| csv.read }
end

Используется для чтения файла CSV в массив Array массивов. Передайте path в файл и любые options параметры, которые понимает CSV::new(). Этот метод также понимает дополнительный параметр :encoding, который можно использовать для указания кодировки Encoding данных в файле, который будет читаться. Вы должны указать его, если ваши данные не в кодировке Encoding::default_external(). CSV будет использовать его для определения способа обработки данных. Вы можете указать вторую кодировку Encoding для преобразования данных при чтении. Например, encoding: "UTF-32BE:UTF-8" будет читать данные UTF-32BE из файла, но преобразовывать их в UTF-8 до того, как CSV их обработает.

readlines(*args) Показать исходный код
# File lib/csv.rb, line 718
def self.readlines(*args)
  read(*args)
end

Псевдоним для CSV::read().

table(path, **options) Показать исходный код
# File lib/csv.rb, line 729
def self.table(path, **options)
  read( path, { headers:           true,
                converters:        :numeric,
                header_converters: :symbol }.merge(options) )
end

Сокращение для:

CSV.read( path, { headers:           true,
                  converters:        :numeric,
                  header_converters: :symbol }.merge(options) )

Общедоступные методы экземпляров

<<(строка) Показать исходный код
# File lib/csv.rb, line 1185
def <<(row)
  writer << row
  self
end

Основной метод записи для обернутых строк и ввода-вывода, row (массив Array или CSV::Row) преобразуется в CSV и добавляется к источнику данных. При передаче CSV::Row добавляются только поля строки fields().

Источник данных должен быть открыт для записи.

Также известен как: add_row, puts
add_row(строка)
Псевдоним для: <<
binmode?() Показать исходный код
# File lib/csv.rb, line 1122
def binmode?
  if @io.respond_to?(:binmode?)
    @io.binmode?
  else
    false
  end
end
col_sep() Показать исходный код
# File lib/csv.rb, line 979
def col_sep
  parser.column_separator
end

Закодированный :col_sep, используемый при разборе и записи. См. CSV::new для подробностей.

convert( имя ) Показать исходный код
convert { |поле| ... }
convert { |поле, информация_о_поле| ... }
# File lib/csv.rb, line 1207
def convert(name = nil, &converter)
  parser_fields_converter.add_converter(name, &converter)
end

Можно использовать этот метод для установки встроенного CSV::Converters или для предоставления блока, обрабатывающего пользовательское преобразование.

Если вы предоставляете блок с одним аргументом, ему будет передано поле, и ожидается, что он вернет преобразованное значение или само поле. Если ваш блок принимает два аргумента, ему также будет передана CSV::FieldInfo Struct, содержащая подробности о поле. Опять же, блок должен вернуть преобразованное поле или само поле.

converters() Показать исходный код
# File lib/csv.rb, line 1014
def converters
  parser_fields_converter.map do |converter|
    name = Converters.rassoc(converter)
    name ? name.first : converter
  end
end

Возвращает текущий список используемых преобразователей. См. CSV::new для подробностей. Встроенные преобразователи будут возвращаться по имени, а другие — как есть.

each(&блок) Показать исходный код
# File lib/csv.rb, line 1235
def each(&block)
  parser_enumerator.each(&block)
end

Возвращает каждую строку источника данных по очереди.

Поддержка Enumerable.

Источник данных должен быть открыт для чтения.

eof()
Псевдоним для: eof?
eof?() Показать исходный код
# File lib/csv.rb, line 1158
def eof?
  begin
    parser_enumerator.peek
    false
  rescue StopIteration
    true
  end
end
Также известен как: eof
field_size_limit() Показать исходный код
# File lib/csv.rb, line 1000
def field_size_limit
  parser.field_size_limit
end

Предел размера поля, если таковой имеется. См. CSV::new для подробностей.

flock(*аргументы) Показать исходный код
# File lib/csv.rb, line 1130
def flock(*args)
  raise NotImplementedError unless @io.respond_to?(:flock)
  @io.flock(*args)
end
force_quotes?() Показать исходный код
# File lib/csv.rb, line 1078
def force_quotes?
  @writer_options[:force_quotes]
end

Возвращает true если все поля вывода заключены в кавычки. См. CSV::new для подробностей.

gets()
Псевдоним для: shift
header_convert( имя ) Показать исходный код
header_convert { |поле| ... }
header_convert { |поле, информация_о_поле| ... }
# File lib/csv.rb, line 1222
def header_convert(name = nil, &converter)
  header_fields_converter.add_converter(name, &converter)
end

Идентично CSV#convert(), но для заголовочных строк.

Обратите внимание, что этот метод необходимо вызвать перед чтением заголовочных строк, чтобы он имел какой-либо эффект.

header_converters() Показать исходный код
# File lib/csv.rb, line 1062
def header_converters
  header_fields_converter.map do |converter|
    name = HeaderConverters.rassoc(converter)
    name ? name.first : converter
  end
end

Возвращает текущий список преобразователей, применяемых к заголовкам. См. CSV::new для подробностей. Встроенные преобразователи будут возвращаться по имени, а другие — как есть.

header_row?() Показать исходный код
# File lib/csv.rb, line 1255
def header_row?
  parser.header_row?
end

Возвращает true если следующая считываемая строка будет заголовочной строкой.

headers() Показать исходный код
# File lib/csv.rb, line 1033
def headers
  if @writer
    @writer.headers
  else
    parsed_headers = parser.headers
    return parsed_headers if parsed_headers
    raw_headers = @parser_options[:headers]
    raw_headers = nil if raw_headers == false
    raw_headers
  end
end

Возвращает nil если заголовки не будут использоваться, true если они будут, но еще не были прочитаны, или фактические заголовки после их чтения. См. CSV::new для подробностей.

inspect() Показать исходный код
# File lib/csv.rb, line 1280
def inspect
  str = ["<#", self.class.to_s, " io_type:"]
  # show type of wrapped IO
  if    @io == $stdout then str << "$stdout"
  elsif @io == $stdin  then str << "$stdin"
  elsif @io == $stderr then str << "$stderr"
  else                      str << @io.class.to_s
  end
  # show IO.path(), if available
  if @io.respond_to?(:path) and (p = @io.path)
    str << " io_path:" << p.inspect
  end
  # show encoding
  str << " encoding:" << @encoding.name
  # show other attributes
  ["lineno", "col_sep", "row_sep", "quote_char"].each do |attr_name|
    if a = __send__(attr_name)
      str << " " << attr_name << ":" << a.inspect
    end
  end
  ["skip_blanks", "liberal_parsing"].each do |attr_name|
    if a = __send__("#{attr_name}?")
      str << " " << attr_name << ":" << a.inspect
    end
  end
  _headers = headers
  str << " headers:" << _headers.inspect if _headers
  str << ">"
  begin
    str.join('')
  rescue  # any encoding error
    str.map do |s|
      e = Encoding::Converter.asciicompat_encoding(s.encoding)
      e ? s.encode(e) : s.force_encoding("ASCII-8BIT")
    end.join('')
  end
end

Возвращает упрощенное описание ключевых атрибутов CSV в совместимой с ASCII String.

ioctl(*аргументы) Показать исходный код
# File lib/csv.rb, line 1135
def ioctl(*args)
  raise NotImplementedError unless @io.respond_to?(:ioctl)
  @io.ioctl(*args)
end
liberal_parsing?() Показать исходный код
# File lib/csv.rb, line 1083
def liberal_parsing?
  parser.liberal_parsing?
end

Возвращает true если недопустимый ввод обрабатывается. См. CSV::new для подробностей.

line() Показать исходный код
# File lib/csv.rb, line 1108
def line
  parser.line
end

Последняя прочитанная строка из этого файла.

lineno() Показать исходный код
# File lib/csv.rb, line 1097
def lineno
  if @writer
    @writer.lineno
  else
    parser.lineno
  end
end

Номер строки последней прочитанной строки из этого файла. Поля с вложенными символами конца строки не повлияют на этот счетчик.

path() Показать исходный код
# File lib/csv.rb, line 1140
def path
  @io.path if @io.respond_to?(:path)
end
puts(строка)
Псевдоним для: <<
END_OF_DOCUMENT_MARKER
quote_char() Показать исходный код
# File lib/csv.rb, line 995
def quote_char
  parser.quote_character
end

Кодированный символ :quote_char используемый при разборе и записи. См. CSV::new для получения подробностей.

read() Показать исходный код
# File lib/csv.rb, line 1244
def read
  rows = to_a
  if parser.use_headers?
    Table.new(rows, headers: parser.headers)
  else
    rows
  end
end

Считывает оставшиеся строки и возвращает Array массивов.

Источник данных должен быть открыт для чтения.

Также алиасируется как: readlines
readline()
Псевдоним для: shift
readlines()
Псевдоним для: read
return_headers?() Показать исходный код
# File lib/csv.rb, line 1048
def return_headers?
  parser.return_headers?
end

Возвращает true , если заголовки будут возвращены как строка результатов. См. CSV::new для получения подробностей.

rewind() Показать исходный код
# File lib/csv.rb, line 1169
def rewind
  @parser = nil
  @parser_enumerator = nil
  @writer.rewind if @writer
  @io.rewind
end

Перематывает объект IO и сбрасывает счётчик строк CSV.

row_sep() Показать исходный код
# File lib/csv.rb, line 987
def row_sep
  parser.row_separator
end

Кодированный символ :row_sep , используемый при разборе и записи. См. CSV::new для получения подробностей.

shift() Показать исходный код
# File lib/csv.rb, line 1266
def shift
  begin
    parser_enumerator.next
  rescue StopIteration
    nil
  end
end

Основной метод чтения для обернутых строк и ввода/вывода, из источника данных извлекается одна строка, анализируется и возвращается как Array полей (если заголовки не используются) или как CSV::Row (при использовании заголовков строк).

Источник данных должен быть открыт для чтения.

Также алиасируется как: gets, readline
skip_blanks?() Показать исходный код
# File lib/csv.rb, line 1073
def skip_blanks?
  parser.skip_blanks?
end

Возвращает true пустые строки пропускаются анализатором. См. CSV::new для получения подробностей.

skip_lines() Показать исходный код
# File lib/csv.rb, line 1005
def skip_lines
  parser.skip_lines
end

Регулярное выражение, отмечающее строку как комментарий. См. CSV::new для получения подробностей

stat(*args) Показать исходный код
# File lib/csv.rb, line 1144
def stat(*args)
  raise NotImplementedError unless @io.respond_to?(:stat)
  @io.stat(*args)
end
to_i() Показать исходный код
# File lib/csv.rb, line 1149
def to_i
  raise NotImplementedError unless @io.respond_to?(:to_i)
  @io.to_i
end
to_io() Показать исходный код
# File lib/csv.rb, line 1154
def to_io
  @io.respond_to?(:to_io) ? @io.to_io : @io
end
unconverted_fields?() Показать исходный код
# File lib/csv.rb, line 1024
def unconverted_fields?
  parser.unconverted_fields?
end

Возвращает true если unconverted_fields() преобразуются в результаты разбора. См. CSV::new для получения подробностей.

write_headers?() Показать исходный код
# File lib/csv.rb, line 1053
def write_headers?
  @writer_options[:write_headers]
end

Возвращает true если заголовки записываются в выходные данные. См. CSV::new для получения подробностей.

Методы частного экземпляра

build_fields_converter(initial_converters, options) Показать исходный код
# File lib/csv.rb, line 1412
def build_fields_converter(initial_converters, options)
  fields_converter = FieldsConverter.new(options)
  normalize_converters(initial_converters).each do |name, converter|
    fields_converter.add_converter(name, &converter)
  end
  fields_converter
end
build_header_fields_converter() Показать исходный код
# File lib/csv.rb, line 1394
def build_header_fields_converter
  specific_options = {
    builtin_converters: HeaderConverters,
    accept_nil: true,
  }
  options = @base_fields_converter_options.merge(specific_options)
  build_fields_converter(@initial_header_converters, options)
end
build_parser_fields_converter() Показать исходный код
# File lib/csv.rb, line 1382
def build_parser_fields_converter
  specific_options = {
    builtin_converters: Converters,
  }
  options = @base_fields_converter_options.merge(specific_options)
  build_fields_converter(@initial_converters, options)
end
build_writer_fields_converter() Показать исходный код
# File lib/csv.rb, line 1407
def build_writer_fields_converter
  build_fields_converter(@initial_write_converters,
                         @write_fields_converter_options)
end
convert_fields(fields, headers = false) Показать исходный код
# File lib/csv.rb, line 1357
def convert_fields(fields, headers = false)
  if headers
    header_fields_converter.convert(fields, nil, 0)
  else
    parser_fields_converter.convert(fields, @headers, lineno)
  end
end

Обрабатывает fields с помощью @converters, или @header_converters если headers передано в качестве true, возвращая преобразованный набор полей. Любой преобразователь, который изменяет поле на что-либо кроме String, прерывает цепочку преобразования для этого поля. Это в первую очередь ускоряет процесс.

determine_encoding(encoding, internal_encoding) Показать исходный код
# File lib/csv.rb, line 1320
def determine_encoding(encoding, internal_encoding)
  # honor the IO encoding if we can, otherwise default to ASCII-8BIT
  io_encoding = raw_encoding
  return io_encoding if io_encoding

  return Encoding.find(internal_encoding) if internal_encoding

  if encoding
    encoding, = encoding.split(":", 2) if encoding.is_a?(String)
    return Encoding.find(encoding)
  end

  Encoding.default_internal || Encoding.default_external
end
header_fields_converter() Показать исходный код
# File lib/csv.rb, line 1390
def header_fields_converter
  @header_fields_converter ||= build_header_fields_converter
end
normalize_converters(converters) Показать исходный код
# File lib/csv.rb, line 1335
def normalize_converters(converters)
  converters ||= []
  unless converters.is_a?(Array)
    converters = [converters]
  end
  converters.collect do |converter|
    case converter
    when Proc # custom code block
      [nil, converter]
    else # by name
      [converter, nil]
    end
  end
end
parser() Показать исходный код
# File lib/csv.rb, line 1420
def parser
  @parser ||= Parser.new(@io, parser_options)
end
parser_enumerator() Показать исходный код
# File lib/csv.rb, line 1429
def parser_enumerator
  @parser_enumerator ||= parser.parse
end
parser_fields_converter() Показать исходный код
# File lib/csv.rb, line 1378
def parser_fields_converter
  @parser_fields_converter ||= build_parser_fields_converter
end
parser_options() Показать исходный код
# File lib/csv.rb, line 1424
def parser_options
  @parser_options.merge(header_fields_converter: header_fields_converter,
                        fields_converter: parser_fields_converter)
end
raw_encoding() Показать исходный код
# File lib/csv.rb, line 1368
def raw_encoding
  if @io.respond_to? :internal_encoding
    @io.internal_encoding || @io.external_encoding
  elsif @io.respond_to? :encoding
    @io.encoding
  else
    nil
  end
end

Возвращает кодировку объекта внутреннего IO.

writer() Показать исходный код
# File lib/csv.rb, line 1433
def writer
  @writer ||= Writer.new(@io, writer_options)
end
writer_fields_converter() Показать исходный код
# File lib/csv.rb, line 1403
def writer_fields_converter
  @writer_fields_converter ||= build_writer_fields_converter
end
writer_options() Показать исходный код
# File lib/csv.rb, line 1437
def writer_options
  @writer_options.merge(header_fields_converter: header_fields_converter,
                        fields_converter: writer_fields_converter)
end

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

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