2

我有一个从 DB 获取的数组。在这个项目中,我将我的数组转换为 csv 文件。但是每次我打开文件时,我都会得到双引号。我尝试使用 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;
4

4 回答 4

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;: the是对第一个匹配组 ( ) 的$1反向引用(^|;)
    $2([^";]+);

假设$line'19.08.2013;47657;"12459 Abdullahi";60;',结果(preg_replace调用后)将是:'19.08.2013;47657;12459 Abdullahi;60;'。引号不见了。

但是,如果某个字段包含一个"字符,它可能会被转义\"

$line = preg_replace('/(?<=^|;)"(.+)"(?=;)/','$1',$line);

区别:

  • (?<=^|;)一个不引人注目的积极回顾。^模式中的下一个内容只有在字符串开头 ( ) 或分号前面时才会匹配
  • (.+)现在是第二组。它匹配所有内容,包括"但:
  • "(?=;)"这仅在 a 后跟 a 时才匹配;

当出现类似 的行时'19.08.2013;47657;"12459 \"Abdullahi\"";60;',后一个表达式将返回19.08.2013;47657;12459 \"Abdullahi\";60;<-- 它只删除了未转义的引号

于 2013-08-19T14:23:18.517 回答
1
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;
于 2017-07-06T08:00:09.890 回答
0

在 CSV 中将单元格值括在引号中通常是有充分理由的。通常是因为单元格值包含列值分隔标记存在危险/恐惧。在解析 CSV 时删除它们可能会造成严重破坏。

在格式良好的 CSV 文件中,如果单元格用引号括起来,则需要对构成单元格值一部分的引号进行转义。转义非常重要,否则读取 CSV 的解析器将无法理解单元格值的开始和结束位置。

不幸的是,犯了错误。您可能在这里,因为您必须解析创建者没有正确转义其 CSV 的 CSV。因此,下面是去除引号的最终方法。以下 RegEx 将删除单元格值的开头和结尾处的引号,但不会删除其中的引号。

$delimiter = ',';
$enclosure = '"';
$row = preg_replace("/(?:(?<=^|{$delimiter}){$enclosure})|(?:{$enclosure}(?=$|{$delimiter}))/",'',$row);

如果您的分隔符是竖线,请确保在其前面加上 2 个反斜杠字符 ( \\|)。

可以在此处找到演示。

于 2019-11-20T21:03:29.000 回答
-1

尝试这个

$array = array('19.08.2013',47657,'"12459 Abdullahi"');
$array = str_replace('"', '', $array);
outputCSV($array);

所以在你的代码中可能是这样的

$transaction_array = str_replace('"', '', $transaction_array);

或检查此线程

使用 fputcsv 时避免使用 csv 文件中的默认引号

于 2013-08-19T14:24:44.483 回答