我有一个从DB获取的数组。在这个项目中,我将我的数组转换为csv文件。但每次我打开文件我得到双重quoetes。我试过str_replace和preg_place没有成功。我该如何删除引号
这是我的csv代码
$query = "SELECT t.transactiontime, t.restaurant_id, t.transactionid, t.cardid, emd.m_field_id_2, t.pricebefordiscount, t.menucard_cut
from transactions as t
left join exp_member_data AS emd ON (t.cardid-10000000 = emd.member_id) order by t.transactiontime desc limit 50";
$transactions_query = ee()->db->query($query);
$transactions_result = $transactions_query->result_array();
$transaction_array = array();
foreach ($transactions_result as $key)
{
$date = new DateTime($key['transactiontime']);
$newdate = $date->format('d.m.Y');
$transaction_array[] = array(
'transactiontime' => $newdate,
'restaurant_id' => $key['restaurant_id'],
'member' => $key['transactionid'] . " " . $key['m_field_id_2'],
'pricebefordiscount' => $key['pricebefordiscount']/100,
'menucard_cut' => $key['menucard_cut']
);
}
function outputCSV($data)
{
$outstream = fopen("php://output", 'w');
function __outputCSV(&$vals, $key, $filehandler)
{
fputcsv($filehandler, $vals, ';');
}
array_walk($data, '__outputCSV', $outstream);
fclose($outstream);
}
outputCSV($transaction_array);
我的输出
19.08.2013;47657;"12459 Abdullahi";60;
19.08.2013;47658;"12455 atima";30;
答案 0 :(得分:2)
报价确实没有错。当一些CSV使用空格作为分隔符时,它们可以避免任何混淆:
data "some more" another thing
//is not the same as:
data some more another thing
但是,如果要删除它们,请将此正则表达式应用于每一行:
$line = preg_replace('/(^|;)"([^"]+)";/','$1$2;',$line);
你应该没事。
它是如何工作的:
(^|;)
匹配(并捕获)行的开头或分号"
匹配文字"
(不捕获)([^" ]+)
:匹配并捕获至少一个不 "
";
:匹配(不捕获)文字"
和;
$1$2;
:$1
是对第一个匹配组((^|;)
)的反向引用
$2
引用([^";]+)
,;
只是文字假设$line
为'19.08.2013;47657;"12459 Abdullahi";60;'
,结果(在preg_replace
调用之后)将为:'19.08.2013;47657;12459 Abdullahi;60;'
。报价不见了。
但是,如果某个字段包含"
个字符,它可能会被转义(\"
),所以为了防止正则表达式无法发现,这是一个使用前瞻的字符串断言:
$line = preg_replace('/(?<=^|;)"(.+)"(?=;)/','$1',$line);
区别:
(?<=^|;)
一个非捕获的正面看法。模式中的下一个内容只有在字符串开头(^
)或分号(.+)
现在是第二组。它匹配所有内容,包括"
BUT:"(?=;)
仅当"
后面跟;
匹配时才匹配{。}}。当显示类似'19.08.2013;47657;"12459 \"Abdullahi\"";60;'
的行时,后一个表达式将返回19.08.2013;47657;12459 \"Abdullahi\";60;
&lt; - 它只删除未转义的引号
答案 1 :(得分:0)
Re write the file and try to parse csv file:
$file_path = "Book1.csv";
$string = file_get_contents($file_path, FILE_USE_INCLUDE_PATH);
echo $string;
echo "<br><br><br>";
$string2 = str_replace('"', " ", $string);
echo $string2;
file_put_contents($file_path, $string2);
exit;
答案 2 :(得分:0)
通常有很好的理由将单元格值括在CSV的引号中。通常是因为存在危险/担心,单元格值包含列值分隔标记。解析CSV时删除它们可能会造成严重破坏。
在格式良好的CSV文件中,如果单元格用引号引起来,则需要转义构成单元格值一部分的引号。转义非常重要,否则读取CSV的解析器将无法理解单元格值的开始和结束位置。
不幸的是,会犯错误。而且您可能在这里,因为您必须在创建者未正确转义其CSV的情况下分析CSV。因此,下面是剥去外壳引号的确定方法。下面的RegEx将删除单元格值的开头和结尾的引号,但不能删除其中的引号。
$delimiter = ',';
$enclosure = '"';
$row = preg_replace("/(?:(?<=^|{$delimiter}){$enclosure})|(?:{$enclosure}(?=$|{$delimiter}))/",'',$row);
如果定界符为竖线,请确保在其前面加上2个反斜杠字符(\\|
)。
可以找到一个演示here。
答案 3 :(得分:-1)
试试这个
$array = array('19.08.2013',47657,'"12459 Abdullahi"');
$array = str_replace('"', '', $array);
outputCSV($array);
所以在您的代码中可能会出现这种情况
$transaction_array = str_replace('"', '', $transaction_array);
或检查此帖子