按逗号拆分字符串,但忽略引号内的逗号

20

示例字符串:

"Foo","Bar, baz","Lorem","Ipsum"

在这里,我们有用逗号分隔的引号内 4 个值。

当我执行这个操作时:

str.split(',').forEach(…

那样也会分割值"Bar, baz",而我不想这样。是否可能使用正则表达式忽略引号内的逗号?


你的引号是否正确平衡?引号内部是否可能存在转义引号?(难道你不需要一个CSV解析器吗?) - Tim Pietzcker
1
当然,这是可以通过正则表达式实现的。 - Kai
@TimPietzcker 嗯,如果我可以通过<script>将其加载到我的管理页面上,我可以使用CSV解析器。 CSV文件是由PayPal生成的,因此我认为它在语法上是有效的。 - Šime Vidas
你实际上需要结果中的引号吗?从你的例子来看,似乎逗号只在分隔引用短语或分隔引用短语内的单词时出现,因此如果是这样一致的话,你应该能够使用 str.slice(1,-1).split('","')。如果您要拆分的逗号周围可以有空格,则可以使用更简单的正则表达式 .split(/"\s*,\s*"/)。如果您需要引号,则可以使用 .map(function(item) { return '"' + item + '"'; }) - cookie monster
@cookiemonster 呵呵,那是个好主意 :) - Šime Vidas
1个回答

62

可以使用正向先行断言来实现。

var str = '"Foo","Bar, baz","Lorem","Ipsum"',
    res = str.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);

console.log(res);  // [ '"Foo"', '"Bar, baz"', '"Lorem"', '"Ipsum"' ]

正则表达式:

,               ','
(?=             look ahead to see if there is:
(?:             group, but do not capture (0 or more times):
(?:             group, but do not capture (2 times):
 [^"]*          any character except: '"' (0 or more times)
 "              '"'
){2}            end of grouping
)*              end of grouping
 [^"]*          any character except: '"' (0 or more times)
$               before an optional \n, and the end of the string
)               end of look-ahead

或者一个负向先行断言

var str = '"Foo","Bar, baz","Lorem","Ipsum"',
    res = str.split(/,(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)/);

console.log(res); // [ '"Foo"', '"Bar, baz"', '"Lorem"', '"Ipsum"' ]

2
这是我尝试允许单引号的代码!str.split(/,(?=(?:(?:[^'"]*(?:'|")){2})*[^'"]*$)/) 如果有错误,请告诉我。需要正确无误! - JohnnyQ
@hwnd,您确实是一个正则表达式巫师,这应该被标记为正确答案。 - Dan Ochiana
修复了此答案中的一些问题(例如未包含引号):https://dev59.com/imgu5IYBdhLWcg3wQE8D#57121244 - thisismydesign

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接