PHP新手求助:preg_split处理带引号字符串的多余引号与部分引号保留问题
解决preg_split处理CSV时的引号问题
嘿,作为PHP新手碰到正则处理CSV的坑太正常了——CSV的引号规则确实容易让人头大!先说说你当前正则的问题:你的表达式尝试通过匹配引号内容再重置匹配位置来分割,但最后一个字段里的引号因为处于字符串末尾,正则的逻辑没有正确处理,导致出现了多余的引号重复。
方案一:修正你的正则表达式
我们可以换一种思路,只分割那些不在成对引号内的逗号,用正则的断言来实现:
$row = 'EL10,40,2019-02-06,55555,2019-01-06,ar@email.com,"Text , random text , 52555885/ 48484848484",Yes,One Two,Broke,2019-01-01,000.00,0.00,0.0,0.0,0.0,0.00,0.00,0.0,VRA "Morning"'; // 先去掉原字符串末尾可能的分号(如果有的话) $row = rtrim($row, ';'); $row_expl = preg_split('/(?<!\"[^"]*)(?=(?:[^"]*\"[^"]*\")*[^"]*$),\s*/', $row);
这个正则的逻辑拆解:
(?<!\"[^"]*):负向后行断言,确保当前逗号前面没有未闭合的引号(也就是前面的引号都是成对出现的)(?=(?:[^"]*\"[^"]*\")*[^"]*$):正向先行断言,确保当前逗号后面的引号总数是偶数(所有引号都能成对闭合),\s*:匹配逗号和后面可选的空格,作为分割符
这样处理后,最后一个字段VRA "Morning"就会被正确保留,不会出现多余引号。
方案二:用PHP内置的CSV处理函数(更推荐!)
其实PHP已经内置了专门处理CSV字符串的函数str_getcsv(),它能完美处理引号内的逗号、转义引号等各种CSV规则,比自己写正则靠谱多了,尤其适合新手:
$row = 'EL10,40,2019-02-06,55555,2019-01-06,ar@email.com,"Text , random text , 52555885/ 48484848484",Yes,One Two,Broke,2019-01-01,000.00,0.00,0.0,0.0,0.0,0.00,0.00,0.0,VRA "Morning";'; $row = rtrim($row, ';'); // 去掉末尾的分号 $row_expl = str_getcsv($row, ',', '"');
这个函数会自动识别引号内的内容,保留里面的逗号,直接返回分割后的数组,完全不用你写复杂的正则,省心又不容易出错!
内容的提问来源于stack exchange,提问作者Simas Šlepikas
相关产品推荐
相关产品推荐

