Можно ли проанализировать текстовый файл с помощью CSV-файла Rust?

#csv #rust

#csv #Ржавчина

Вопрос:

У меня есть текстовый файл с несколькими строками. Можно ли использовать csv-файл Rust для его анализа таким образом, чтобы каждая строка анализировалась в отдельную запись?

Я попытался указать b'n' в качестве разделителя полей и оставил по умолчанию ограничитель записи. Проблема, с которой я сталкиваюсь, заключается в том, что строки иногда могут заканчиваться, rn а иногда и просто n . Однако это вызывает UnequalLengths ошибку, если flexible опция не указана, потому что, по-видимому, новые строки имеют приоритет над разделителями полей, поэтому приведенный ниже код:

 use csv::{ByteRecord, Reader as CsvReader, ReaderBuilder, Terminator};

fn main() { 
    let data = "foo,foo2rnbar,bar2nbazrn";
    let mut reader = ReaderBuilder::new()
        .delimiter(b'n')
        .has_headers(false)
        .flexible(true)
        .from_reader(data.as_bytes());
    let mut record = ByteRecord::new();
    loop {
        match reader.read_byte_record(amp;mut record) {
            Ok(true) => {},
            Ok(false) => { break },
            Err(csv_error) => {
                println!("{}", csv_error);
                break;
            }
        }
        println!("fields: {}", record.len());
        for field in record.iter() {
            println!("{:?}", ::std::str::from_utf8(amp;field))
        }
    }
}
  

Будет ли напечатан:

 fields: 1
Ok("foo,foo2")
fields: 2
Ok("bar,bar2")
Ok("baz")
  

Я бы хотел, чтобы строка была разделена на 3 записи по одному полю в каждой, поэтому ожидаемый результат будет:

 fields: 1
Ok("foo,foo2")
fields: 1
Ok("bar,bar2")
fields: 1
Ok("baz")
  

Можно ли как-то настроить программу чтения CSV, чтобы добиться такого поведения?

Концептуально я бы хотел, чтобы терминатор поля был None , но кажется, что терминатор должен быть одним u8 значением

Комментарии:

1. Можно ли использовать csv-файл Rust для его анализа таким образом, чтобы каждая строка анализировалась в отдельную запись? Именно так обычно работают CSV-файлы. Вы спрашиваете, возможно ли проанализировать его так, чтобы каждая строка была отдельным полем ?

2. Не могли бы вы также предоставить ожидаемый / желаемый результат, чтобы мы могли сделать вывод, когда ответим на вопрос?

3. Хорошо … так зачем вы csv вообще используете, если вам не нужны разделители полей? Я немного смущен этим вопросом, потому что это похоже на проблему, которой не существует. Например, если бы вы спросили: «Как мне затупить ножницы, чтобы не порезаться на беговой дорожке?» Логичным продолжением было бы: «Зачем вообще носить ножницы на беговой дорожке?»

4. Я автор csv-файла, и я не думаю, что вам следует использовать csv-файл для этой задачи. Этот вопрос заставил меня понять, что анализатор csv должен или, возможно, возвращать ошибку (или панику), если вызывающие абоненты устанавливают разделитель и разделитель записей на одно и то же. Итак, я бы сказал, что ответ на ваш вопрос: «Возможно, но это не гарантирует работу и является неправильным использованием ящика». Просто проанализируйте свой формат вручную.

5. В противном случае ответ будет «использовать lines метод» и вообще не использовать ящик.

Ответ №1:

Думаю, я повторно опубликую свой комментарий в качестве ответа. Более кратко, как автор csv ящика, я бы сказал, что ответ на ваш вопрос «нет».

Во-первых, мне непонятно, почему вы вообще пытаетесь использовать анализатор csv для этой задачи. Как указывают комментарии, вполне вероятно, что ваш вопрос не указан. Тем не менее, кажется более разумным просто написать свой собственный анализатор.

Во-вторых, установка для разделителя и ограничителя одного и того же значения, вероятно, является условием, при котором читатель csv должен паниковать или возвращать ошибку. На самом деле это не имеет смысла с точки зрения синтаксического анализатора, и его поведение, вероятно, не определено.

Наконец, мне кажется, что ваш желаемый результат указывает на то, что вы должны просто перебирать строки в вашем вводе. Он должен дать вам именно тот результат, который вы хотите, поскольку он обрабатывает оба n и rn .