2015-09-27 3 views
1

Я пытаюсь разобрать через запятую строку с помощью:Как разобрать запятую (CSV) с некоторыми элементами в кавычках?

val array = input.split(",") 

Затем я заметил, что некоторые входные строки имеют «» внутри кавычек:

data0, "data1", data2, data3, "data4-1, data4-2, data4-3", data5 

* Обратите внимание, что данные не очень чистые, поэтому некоторые поля в кавычках, а некоторые не


Как разбить такую ​​строку в:

array(0) = data0 
array(1) = data1 
array(2) = data2 
array(3) = data3 
array(4) = data4-1, data4-2, data4-3 
array(5) = data5 
+3

Разбор CSV-файлов может быть печально из-за его поведения вокруг котировок, а также запятых и котировок, включенных в приведенные значения. Я рекомендую вытащить библиотеку, которая хорошо рассматривается для надежного решения всех дел. Параметры, которые вы могли бы рассмотреть, включают [scala-csv] (https://github.com/tototoshi/scala-csv) и [traversable-csv] (http://labs.encoded.io/2012/04/09/reading -csv-файлы-в-лестница-з-проходимой-полосной /). Или используйте библиотеку Java, такую ​​как [opencsv] (http://opencsv.sourceforge.net/). – Shadowlands

+0

В противном случае, если вы не хотите или не можете использовать библиотеку, вы можете посмотреть [этот ответ SO] (http://stackoverflow.com/questions/5063022/use-scala-parser-combinator-to- parse-csv-files/5063652 # 5063652) или [этот ответ SO] (http://stackoverflow.com/questions/32488364/whats-a-simple-scala-only-way-to-read-in-and-then -write-out-a-small-csv-file/32488453 # 32488453), чтобы узнать, как другие решают ваши собственные синтаксические анализаторы CSV. – Shadowlands

+0

@Shadowlands Не могли бы вы обобщить ваши комментарии в ответе (так как я думаю, вы показали множество ценных подходов, другие могут извлечь выгоду.) Thx. –

ответ

5

В соответствии с моими комментариями:

Синтаксический CSV файлы могут быть как известно, сложно из-за его поведения вокруг кавычки и запятые и кавычки, включенных в цитируемых значений. Я рекомендую вытащить библиотеку, которая хорошо рассматривается для надежного решения всех дел.

Возможные варианты: scala-csv и traversable-csv. Или используйте библиотеку Java, такую ​​как opencsv.

В противном случае, если вы не хотите или не можете использовать библиотеку, вы можете посмотреть this SO answer или this SO answer, чтобы узнать, как другие решали ваши собственные синтаксические анализаторы.

+1

Спасибо Shadowlands! Я хотел бы использовать библиотеку, если это возможно. Одна из проблем, которую я имею здесь, вместо того, чтобы иметь «один файл csv», я получу «строки csv», которые мне нужно проанализировать. Есть ли библиотека, которая могла бы анализировать строку вместо целого файла? Спасибо! – Edamame

-1

Вы можете разделить эту строку с выражением регулярного выражения.

val s = """data0, "data1", data2, data3, "data4-1, data4-2, data4-3", data5""" 

"""((".*?")|('.*?')|[^"',]+)+""".r.findAllIn(s).foreach(println) 

кстати. любая библиотека, которая может анализировать файлы csv, также может анализировать одну строку csv. Просто заверните строку в StringReader.

+0

Спасибо! Не могли бы вы подробнее рассказать о «любой библиотеке, которая может анализировать файлы csv, также может анализировать одну строку csv». Например, как мне изменить следующий синтаксический анализатор файла для синтаксического анализа одной строки csv? CSVReader reader = новый CSVReader (новый FileReader ("yourfile.csv")); – Edamame

+0

Это должно работать так: «CSVReader reader = новый CSVReader (новый StringReader (« data1, data2, data3 »))' – SpiderPig

0

Я бы рекомендовал использовать CSV-библиотеку для анализа данных CSV - формат беспорядок и больно, чтобы получить право.

Я бы предложил kantan.csv, главным образом потому, что я автор, но также потому, что он позволяет вам немного дальше, чем превращать поток CSV в список массивов строк. Возьмем, к примеру, следующий ввод:

1,Foo,2.0 
2,Bar,false 

Используя kantan.csv, вы можете написать:

import kantan.csv.ops._ 

new File("path/to/csv").asUnsafeCsvRows[(Int, String, Either[Float, Boolean])](',', false) 

Вызов toList на результат даст:

List((1,Foo,Left(2.0)), (2,Bar,Right(false))) 

Обратите внимание, как последний столбец является либо float, либо логическим, но это фиксируется в типе каждого элемента итератора.

0

Ниже мое решение для разбора CSV строку:

String[] res = row.split(";"); 
for (int i = 0; i < res.length; i++) { 
    res[i] = deQuotes(res[i]); 
} 
return res; 

удалить кавычки с REGEXP:

static final Pattern PATTERN_DE_QUOTES = Pattern.compile("(?i)^\\\"(.*)\\\"$"); 

static String deQuotes(String s) { 
    Matcher matcher; 
    if ((matcher = PATTERN_DE_QUOTES.matcher(s)).find()) { 
     return matcher.group(1).replaceAll("\"\"", "\""); 
    } 
    return s; 
} 

Я надеюсь, что это поможет.

Смежные вопросы