Tarang
Tarang

Reputation: 75975

CSV remove commas in quotation marks with regexp

I have a CSV file and we know excel does its thing with commas in a field by enclosing them in double quotation marks for instance i have a file

Product Name,Product Code
Product 1,AAA
"Prod,A,B",BBB

How can I use RegExp to replace the quotation marks with "." instead but only within quotation marks so i get

Product Name,Product Code
Product 1,AAA
Prod.A.B,BBB

as output

Upvotes: 1

Views: 3236

Answers (2)

DaveRandom
DaveRandom

Reputation: 88697

CSV handling functions (fgetcsv(), fputcsv()) are much better for this - they will handle edge cases and will likely be far more reliable than any regex you can come up with.

// Open the file
$fp = fopen($pathToCsvFile, 'r+');

// Create an array of modified data
$tmp = array();
while (($row = fgetcsv($fp, 8192)) !== FALSE) {
  foreach ($row as &$field) $field = str_replace(',', '.', $field);
  $tmp[] = $row;
}

// Truncate the file and put the pointer at the beginning
ftruncate($fp, 0);
rewind($fp);

// Write the modified data back and close the file
foreach ($tmp as $row) {
  fputcsv($fp, $row);
}
fclose($fp);

EDIT Following your comment about not wanting to read from/write to disk, you can do this:

// Lets say the raw CSV data is held in this variable as a string
$rawCsvData = 'Product Name,Product Code
Product 1,AAA
"Prod,A,B",BBB';

// Open a virtual file pointer to memory and fill it with your data
$fp = fopen('php://memory', 'w+');
fwrite($fp, $rawCsvData);

// Start from the beginning of the pointer
rewind($fp);

// ... INSERT CODE FROM ABOVE HERE (minus the fopen()/fclose())

$modifiedCsvData = stream_get_contents($fp);
fclose($fp);

Upvotes: 6

James L.
James L.

Reputation: 4097

This will do multiple replaces, and remove the quotes.

<?php
$data = 'Product Name,Product Code
Product 1,AAA
"Prod,A,B",BBB';

$rgx = '/"(.+?)"/';

preg_match_all($rgx, $data, $matches);
$x = 0; $max = count($matches[0]);
while($x < $max){
    $replace = str_replace(",", ".", $matches[1][$x]);
    $data = str_replace($matches[0][$x], $replace, $data);
    $x++;
}
echo $data;
?>

Upvotes: 2

Related Questions