2014-12-26 4 views
2

Я использую библиотеку Swiftcsv для разбора CSV-файла. Как игнорировать разделитель запятой для строк в DoubleQuotes, например, «Abcd, отправился в Apple»? здесь анализатор принимает Abcd как одно значение и отправился в Apple в качестве другого значения.Поддержка парсинга SwiftCsv для DoubleQuotes

Код:

func parseRows(fromLines lines: [String]) -> [Dictionary<String, String>] { 
    var rows: [Dictionary<String, String>] = [] 

    for (lineNumber, line) in enumerate(lines) { 
     if lineNumber == 0 { 
      continue 
     } 

     var row = Dictionary<String, String>() 
     let values = line.componentsSeparatedByCharactersInSet(self.delimiter) 
     for (index, header) in enumerate(self.headers) { 
      let value = values[index] 
      row[header] = value 
     } 
     rows.append(row) 
    } 

    return rows 
} 

Как я могу изменить line.componentsSeparatedByCharactersInSet (self.delimiter) игнорировать запятые внутри Doublequotes?

ответ

1

Я не знаю, если вы все еще ищете решение, но я просто придумал быстрый способ сделать это, поскольку это проблема, которая только что пришла ко мне.

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

func parseRows(fromLines lines: [String]) -> [Dictionary<String, String>] { 
    var rows: [Dictionary<String, String>] = [] 

    for (lineNumber, line) in enumerate(lines) { 
     if lineNumber == 0 { 
      continue 
     } 

     var row = Dictionary<String, String>() 

     // escape commas in the string when it is surrounded by quotes 

     let convertedLine = NSString(string: line) // have to convert string to NSString because string does not have all NSString API 

     var escapedLine = line 

     var searchRange = NSMakeRange(1,convertedLine.length) 
     var foundRange:NSRange 

     if NSString(string: line).containsString("\"") 
     { 
      while (searchRange.location < convertedLine.length) { 
       searchRange.length = convertedLine.length-searchRange.location 
       foundRange = convertedLine.rangeOfString("\"", options: nil, range: searchRange) 
       if (foundRange.location != NSNotFound) { 
        // found a quotation mark 
        searchRange.location = foundRange.location+foundRange.length 
        let movieTitle = convertedLine.substringToIndex(foundRange.location) 

        escapedLine = convertedLine.stringByReplacingOccurrencesOfString(",", withString: "&c", options: nil, range: NSMakeRange(0,foundRange.location)) 
       } else { 
        // no more substring to find 
        break 
       } 
      } 
     } 

     var values = escapedLine.componentsSeparatedByCharactersInSet(self.delimiter) 

     for (index, header) in enumerate(self.headers) { 
      var value = values[index] 

      //reinsert commas if they were escaped and get rid of quotation marks 
      value = value.stringByReplacingOccurrencesOfString("\"", withString: "") 
      value = value.stringByReplacingOccurrencesOfString("&c", withString: ",") 

      row[header] = value 
     } 
     rows.append(row) 
    } 

    return rows 
} 
+0

плохой проверить, спасибо – Metalhead1247

+0

Одно из значений моего поля CSV - «Вашингтон, округ Колумбия», это не работает. Я получил эту ошибку: фатальная ошибка: индекс массива вне диапазона. – duyn9uyen

3

Используйте это вместо https://github.com/Daniel1of1/CSwiftV

Если бы тот же вопрос. Мне потребовался час или около того, чтобы понять, что проблема заключается в том, что SwiftCSV не работает.

Текст в файлах CSV находится внутри кавычек, поэтому запятые и символы новой строки в CSV не испортят парсер. Я посмотрел на источник SwiftCSV, и для этого нет никакой поддержки, а это означает, что любые запятые или символы новой строки испортят разбор.

Вы можете исправить SwiftCSV или просто пойти с CSwiftV Я связался выше.

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