2011-11-15 88 views
4

有沒有像樣的CSV解析器庫的問題JavaScript?我已經使用thisthat迄今爲止的解決方案。在第一個解決方案一個新的行不會爲新的副陣列,也代碼告訴某某,第二個解決方案分別不會對文本文件<CR><LF>工作在Windows格式化\r\nJavaScript CSV解析器庫

是它創造足以應用

text = text.replace("\r",""); 

到Windows CSV文件?這實際上有效,但我認爲這有點怪癖。是否有csv解析器比隨機博客解決方案更常見?

回答

4

這裏的 '易' 解決方案

csv.split(/\r\n|\r|\n/g) 

它處理:

  • \ n
  • \ r
  • \ r \ n
  • \ n \ r

不幸的是,它打破在包含分隔符之間換行字符值。

例如,下面一行進入...

"this is some","valid CSV data","with a \r\nnewline char" 

會打破它,因爲「\ r \ n」將被錯誤地解釋爲一個條目的結束。

要獲得完整的解決方案,最好的辦法是創建一個ND-FSM(非確定性有限狀態機)詞法分析器/解析器。如果您曾聽說過Chomsky Hierarchy,則可將CSV解析爲III型語法。這意味着逐個字符或逐個令牌地處理狀態跟蹤。

我有一個完全符合RFC 4180兼容的客戶端庫可用,但不知何故,我吸引了外部鏈接的刪除快樂國防部的注意。如果你有興趣,我的個人資料中有一個鏈接。否則,祝你好運。

我會給你公平的警告,CSV看起來很容易。在研究了數十次/數百次實現之後,我只看到了3個JavaScript解析器,它們完成了符合規範的合理工作,並且都沒有完全符合RFC。我成功地寫了一篇,但只有在社區的幫助下,以及很多疼痛

2

如果你在Node工作,有一個很好的CSV parser,可以處理大量的數據(> GB文件)並支持轉義字符。

如果您使用的是瀏覽器JS,那麼仍然可以從code中提取處理邏輯,以便它對字符串(而不是節點Stream)進行操作。

2

下面是做到這一點的一種方法:

// based on json_parse from JavaScript The Good Part by D. Crockford 
var csv_parse = function() { 
    var at, 
     ch, 
     text, 
     error = function (m) { 
      throw { 
       name: 'SyntaxError', 
       message: m, 
       at: at, 
       text: text 
      }; 
     }, 
     next = function (c) { 
      if (c && c !== ch) { 
       error("Expected '" + c + "' instead of '" + ch + "'"); 
      } 

      ch = text.charAt(at); 
      at += 1; 
      return ch; 
     }, 
     //needed to handle "" which indicates escaped quote 
     peek = function() { 
      return text.charAt(at); 
     }, 
     white = function() { 
      while (ch && ch <= ' ' && ch !== '\n') { 
       next(); 
      } 
     }, 
     // if numeric, then return number 
     number = function() { 
      var number, 
       string = word(); 

      number = +string; 
      if (isNaN(number)) { 
       return string; 
      } else { 
       return number; 
      } 
     }, 
     word = function() { 
      var string = ''; 
      while (ch !== ',' && ch !== '\n') { 
       string += ch; 
       next(); 
      } 
      return string; 
     }, 
     // the matching " is the end of word not , 
     // need to worry about "", which is escaped quote 
     quoted = function() { 
      var string =''; 

      if (ch === '"') { 
       while (next()) { 
        if (ch === '"') { 
         //print('need to know ending quote or escaped quote'); 
         // need to know ending quote or escaped quote ("") 
         if (peek() === '"') { 
          //print('maybe double quote near '+string); 
          next('"'); 
          string += ch; 
         } else { 
          next('"') 
          return string; 
         } 
        } else { 
         string += ch; 
        } 
       } 
       return string; 
      } 
      error("Bad string"); 
     }, 
     value = function() { 
      white(); 

      switch(ch) { 
      case '-': 
       return number(); 
      case '"': 
       return quoted(); 
      default: 
       return ch >= '0' && ch <= '9' ? number() : word(); 
      } 

      return number(); 
     }, 
     line = function() { 
      var array = []; 
      white(); 
      if (ch === '\n') { 
       next('\n'); 
       return array;//empty [] 
      } 
      while (ch) { 
       array.push(value()); 
       white(); 
       if (ch === '\n') { 
        next('\n'); 
        return array;//got something 
       } 
       next(',');// not very liberal with delimiter 
       white(); 
      } 
     }; 


    return function (_line) { 
    var result; 
    text = _line; 
    at = 0; 
    ch = ' '; 
    result = line(); 
    white(); 
    if (ch) { 
     error("Syntax error"); 
    } 
    return result; 
    }; 
}(); 
0

我的功能很紮實,只需放入並使用,我希望它對您有所幫助。

csvToArray V1.3

緊湊(508個字節),但符合函數到CSV字符串轉換成一個二維數組,符合標準RFC4180。

http://code.google.com/p/csv-to-array/

常見的用法:jQuery的

$.ajax({ 
     url: "test.csv", 
     dataType: 'text', 
     cache: false 
}).done(function(csvAsString){ 
     csvAsArray=csvAsString.csvToArray(); 
}); 

普遍使用的JavaScript

csvAsArray = csvAsString.csvToArray(); 

覆蓋字段分隔

csvAsArray = csvAsString.csvToArray("|"); 

覆蓋[R的eCord隔板

csvAsArray = csvAsString.csvToArray("", "#"); 

覆蓋跳過標題

csvAsArray = csvAsString.csvToArray("", "", 1); 

覆蓋所有

csvAsArray = csvAsString.csvToArray("|", "#", 1);