我在这个问题中使用joker83的答案:在PHP中解析CSV的正则表达式,但我发现它无法解析字段值正确包含逗号的CSV字符串。是否有可能改进这个regexp来解决这个问题?
joker83: /,(?=(?:[^'"])*(?![^'"]))/
模式的解释。
1. ,(?=x)
表示模式x后面的逗号。
2. [^'"]
表示双引号以外的字符。
3.(?:[^'"])
表示匹配括号子模式,但不将其捕获到匹配的结果数组中。
4. *
表示指定模式的0个或多个。
5. (x)*
表示模式x的0个或多个。
6. y?![^'"]
表示y不跟随某个非双引号的字符(即:匹配双引号后面的y
7. 整个含义是匹配双引号后面的逗号(其中*表示零),或者匹配一个逗号后面的一个或多个字符,而不是双引号,这些字符后面的双引号
如您所见,如果csv字符串是120,"我爱"Lexi Belle","Proxy Paige"","好东西",那么当在preg_split中应用此regexp时,我们将得到4个字段(即 120
"""I Love Lexi Bell""
""Proxy Piage"""
** "good stuff"**
)而不是正确的3个字段。
注意:我正在使用PHP5.2.6(不能升级到新版本,因为我花了很多时间安装一个oci8,可以读取Oracle 8i在Windows上。我无法在新版本的PHP中正确安装它们)。
注意:我也不能使用fgetcsv(),因为输入的csv文件在csv字符串中包含LF代码,fgetcsv()将在该字段的中间分割换行符。
你可以使用这个正则表达式:
/,(?=([^'"]*'"[^'"]*'")*[^'"]*$)/
这是从这个stackoverflow条目中找到的Java:分割逗号分隔的字符串,但忽略引号中的逗号(但对于Java)。
在你的字符串上,它给出:
array(3) {
[0]=>
string(3) "120"
[1]=>
string(31) ""I love Lexi Bell, Proxy Paige""
[2]=>
string(12) ""good stuff""
}
请注意,你仍然有'"在上面。
为什么不使用str_getcsv?
$string = '120,"I love Lexi Bell, Proxy Paige","good stuff"';
$parsedCsv = str_getcsv($string);
print_r($parsedCsv);