2014-09-23 28 views
0

我有一个需要解析的CSV文件类型。下面的正是我需要考虑(缺少列标题,引号内换行,丢失数据等)的条件:RegExp适用于String.match,但不适用于String.split

ID,NAME,TITLE,DESCRIPTION,, 
PRO1234,"JOHN SMITH",ENGINEER,"JOHN HAS BEEN WORKING 

HARD ON BEING A GOOD 

SERVENT." 
PRO1235,"KEITH SMITH",ENGINEER,"keith has been working 

hard on being a good 

servent." 
PRO1235,"KENNY SMITH",,"keith has been working 

hard on being a good 

servent." 
PRO1235,"RICK SMITH",,, 

你会发现,有行以及换行说明内部将用于新的数据行。

我写这个正则表达式查找换行符报价之外,它的伟大工程here

代码,如何使用Node.js:

var fs = require('fs'); 

function parseCSV(filename){ 
    var rx = new RegExp(/\n(?=([^"\\]*(\\.|"([^"\\]*\\.)*[^"\\]*"))*[^"]*$)/g); 
    var strFile = fs.readFileSync(filename).toString(); 
    console.log("line feed count via match: " + strFile.match(rx).length); 
    var csv = strFile.split(rx); 

    console.log("csv length: " + csv.length); 
    console.log("csv items ###############################"); 
    csv.forEach(function(e,i,a){ 
     console.log("item e: " + e); 
    }); 
} 

当我运行这个,你”会看到换行计数(按匹配找到的换行)是正确的,即。然而,使用与String.split()相同的RET时,它回来了所得阵列是不稳定的:

line feed count via match: 4 
csv length: 17 
csv items ############################### 
item e: ID,NAME,TITLE,DESCRIPTION,, 
item e: 
PRO1235,"RICK SMITH" 
item e: "RICK SMITH" 
item e: undefined 
item e: PRO1234,"JOHN SMITH",ENGINEER,"JOHN HAS BEEN WORKING 

HARD ON BEING A GOOD 

SERVENT." 
item e: 
PRO1235,"RICK SMITH" 
item e: "RICK SMITH" 
item e: undefined 
item e: PRO1235,"KEITH SMITH",ENGINEER,"keith has been working 

hard on being a good 

servent." 
item e: 
PRO1235,"RICK SMITH" 
item e: "RICK SMITH" 
item e: undefined 
item e: PRO1235,"KENNY SMITH",,"keith has been working 

hard on being a good 

servent." 
item e: PRO1235,"RICK SMITH" 
item e: "RICK SMITH" 
item e: undefined 
item e: PRO1235,"RICK SMITH",,, 

我在做什么毛病分裂?我的想法是,如果我能确定4个与match()完美配合的换行符,那么同一个regEx应该提供将字符串“分割”的位置。

+1

重新发明轮子的经典案例。 [为什么不使用专用的CSV解析器?](https://code.google.com/p/jquery-csv/) – anubhava 2014-09-23 16:46:19

+0

首先,您不能从中间开始解析字符串。 – sln 2014-09-23 17:01:17

+0

sln - 你能解释一下你的评论吗?如果我调用string.split(regExp),如何解析中间的字符串? – neoRiley 2014-09-23 17:10:59

回答

0

感谢anubhava为他们的答案,这只是正常工作:

var $ = jQuery = require('jquery'); 
var csv = require('./jquery.csv-0.71.min.js'); 
var fs = require('fs'); 

var strFile = fs.readFileSync("./data/TestData.csv").toString(); 
var obj = $.csv.toObjects(strFile); 
var str = JSON.stringify(obj, null, 4); 

console.log("str: " + str); 

谁不喜欢一组新的轮毂?

在我的防守中,我尝试了3个节点上的工具,并且所有3个都是为最简单的情况和文件编写的。

1

你有太多的捕获组。 Split在分割字符串时将返回捕获的组。 请考虑以下简单示例:

var simpleString = "111aaa222bbb"; 
var regxNoCaptureGroup = /\d+/; 
var regxWithCaptureGroup = /(\d+)/; 
var regxWithNoncapturingGroup = /(?:\d+)/; 

simpleString.split(regxNoCaptureGroup); //["", "aaa", "bbb"] 
simpleString.split(regxWithNoncapturingGroup); //same as above 
simpleString.split(regxWithCaptureGroup); //["", "111", "aaa", "222", "bbb"] - includes captured groups 

您在捕获组内有捕获组。请记住,split会找到该组,并将其移除以找到拆分部分,因此拆分数字(如第一个示例中所示)将仅返回字母。 在你的情况下,它将删除捕获的内容。 对于捕获组,它会将结果返回给它们 - 所以如果你打算使用正则表达式分割,你应该建立一个很好的正则表达式,它只捕获需要的东西。

+0

谢谢Etai,我会看看我的regExp - 我很感谢你的解释和时间 - 这确实有道理。 – neoRiley 2014-09-23 17:18:08

+0

np。既然它回答你关于分裂vs比赛的问题,请随时将其标记为接受的答案:) – Etai 2014-09-23 17:19:05

相关问题