Spec-Zone.ru › Ruby 2.7

класс 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,Engineering,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 469
def 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 508
def 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 533
def 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 для указания базового Encoding кодирования для вывода, если не передаётся String строка. CSV нуждается в этой подсказке, если вы планируете выводить данные, несовместимые с ASCII.

generate_line(row, **options) Показать исходный код
# File lib/csv.rb, line 561
def 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

Этот метод — это сокращение для преобразования одной строки (Array) в 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 429
def 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 параметров.

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

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) Show source
# File lib/csv.rb, line 921
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?

  if data.is_a?(String)
    @io = StringIO.new(data)
    @io.set_encoding(encoding || data.encoding)
  else
    @io = data
  end
  @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
  @parser_enumerator = nil
  @eof_error = 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

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

:unconverted_fields

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

:headers

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

:return_headers

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

:write_headers

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

:header_converters

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

:skip_blanks

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

:force_quotes

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

:skip_lines

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

:liberal_parsing

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

:nil_value

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

:empty_value

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

:quote_empty

При установке значения true, CSV будет заключать пустые значения в двойные кавычки. Когда false, CSV будет выводить пустую строку для пустого значения поля.

:write_converters

Преобразует значения в каждой строке с помощью указанного объекта (объектов) Proc, которые получают значение String и возвращают значение String или nil. Когда указан массив, каждый конвертер будет применён по порядку.

:write_nil_value

При значении String, значение (значения) nil в каждой строке будут заменены указанным значением.

:write_empty_value

При значении String или nil, пустое значение (значения) в каждой строке будут заменены указанным значением.

:strip

При установке значения true, CSV удалит «trnfv» вокруг значений. Если вы укажете строку вместо true, CSV удалит строку. Длина строки должна быть 1.

См. 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 635
def 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, когда блок не предоставлен. (Примечание: это отличается от библиотеки CSV Ruby 1.8, которая передавала строки в блок. Используйте 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 679
def parse(str, **options, &block)
  csv = new(str, **options)

  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 699
def parse_line(line, **options)
  new(line, **options).shift
end

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

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

read(path, **options) Показать исходный код
# File lib/csv.rb, line 714
def 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(path, **options) Показать исходный код
# File lib/csv.rb, line 719
def readlines(path, **options)
  read(path, **options)
end

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

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

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

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

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

<<(строка) Показать исходный код
# File lib/csv.rb, line 1229
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 1161
def binmode?
  if @io.respond_to?(:binmode?)
    @io.binmode?
  else
    false
  end
end
col_sep() Показать исходный код
# File lib/csv.rb, line 1008
def col_sep
  parser.column_separator
end

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

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

Этот метод позволяет установить встроенный CSV::Converters или предоставить блок для обработки пользовательской конвертации.

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

converters() Показать исходный код
# File lib/csv.rb, line 1049
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 1279
def each(&block)
  parser_enumerator.each(&block)
end

Поочерёдно выводит каждую строку источника данных.

Поддержка Enumerable.

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

eof()
Псевдоним для: eof?
eof?() Показать исходный код
# File lib/csv.rb, line 1197
def eof?
  return false if @eof_error
  begin
    parser_enumerator.peek
    false
  rescue MalformedCSVError => error
    @eof_error = error
    false
  rescue StopIteration
    true
  end
end
Также алиас для: eof
field_size_limit() Показать исходный код
# File lib/csv.rb, line 1032
def field_size_limit
  parser.field_size_limit
end

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

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

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

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

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

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

header_converters() Показать исходный код
# File lib/csv.rb, line 1101
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 1299
def header_row?
  parser.header_row?
end

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

headers() Показать исходный код
# File lib/csv.rb, line 1069
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 1328
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 1174
def ioctl(*args)
  raise NotImplementedError unless @io.respond_to?(:ioctl)
  @io.ioctl(*args)
end
liberal_parsing?() Показать исходный код
# File lib/csv.rb, line 1122
def liberal_parsing?
  parser.liberal_parsing?
end

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

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

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

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

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

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

Кодированный :quote_char символ, используемый при парсинге и записи. Подробнее см. CSV::new.

read() Показать исходный код
# File lib/csv.rb, line 1288
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 1084
def return_headers?
  parser.return_headers?
end

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Приватные методы экземпляра

build_fields_converter(initial_converters, options) Показать исходный код
# File lib/csv.rb, line 1460
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 1442
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 1430
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 1455
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 1405
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 1368
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 1438
def header_fields_converter
  @header_fields_converter ||= build_header_fields_converter
end
normalize_converters(converters) Показать исходный код
# File lib/csv.rb, line 1383
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 1468
def parser
  @parser ||= Parser.new(@io, parser_options)
end
parser_enumerator() Показать исходный код
# File lib/csv.rb, line 1477
def parser_enumerator
  @parser_enumerator ||= parser.parse
end
parser_fields_converter() Показать исходный код
# File lib/csv.rb, line 1426
def parser_fields_converter
  @parser_fields_converter ||= build_parser_fields_converter
end
parser_options() Показать исходный код
# File lib/csv.rb, line 1472
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 1416
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 1481
def writer
  @writer ||= Writer.new(@io, writer_options)
end
writer_fields_converter() Показать исходный код
# File lib/csv.rb, line 1451
def writer_fields_converter
  @writer_fields_converter ||= build_writer_fields_converter
end
writer_options() Показать исходный код
# File lib/csv.rb, line 1485
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