I want to split a TSV string. The structure is:
abc\tdef\tghi\tjklm
where \t is a tab character.
If I use preg_split to split such string $i
$field=preg_split("/\t/", $i);
$field[3] is jklm.
However, if I have another string
abc\tdef\t\t
$field[3] is not a valid index.
How can I force empty fields into $field, such that all $field arrays would have an equal number of indexes?
If your problem just for extracting Tab Separator Value data, you can use built
in php function (fgetcsv()). It is more stable than use our own function. Please try this
if (($handle = fopen("test.csv", "r")) !== FALSE) {
// extract csv using tab delimiter
while (($data = fgetcsv($handle, 1000, "\t")) !== FALSE) {
print_r($data);
}
fclose($handle);
}
Like this?
$str ="abc\tdef\t\t";
Var_dump(explode("\t", $str));
https://3v4l.org/7qOPJ
Related
I am converting a Delimited FLAT file to CSV and it has some data which as comma in between them. For eg the product name Iphone 6splus, 32 gb. Since this a description of the product and can have special characters also. How do i escape the comma as because of this fputcsv is considering this data as a new line. which is wrong. I am using
$handle = fopen("data.txt", "r");
$lines = [];
$row_count=0;
if (($handle = fopen("data.txt", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, "\t")) !== FALSE) {
if($row_count>0)
{
$lines[] = $data;
}
$row_count++;
}
fclose($handle);
}
$fp = fopen('example.csv', 'w');
foreach ($lines as $line) {
fputcsv($fp, split('\*\*', $line));
}
fclose($fp);
I need to escape the value before i start converting the data and store into csv
Enclose the field in quotes, e.g.
field1_value,field2_value,"field 3,value",field4, etc...
To encode a quote, use ", a single quote symbol in a field will be encoded as "", and the whole field will become """". So if you see the following in e.g. Excel:
---------------------------------------
| regular_value |,,,"| ,"", |""" |"|
---------------------------------------
the CSV file will contain:
regular_value,",,,""",","""",","""""""",""""
A comma is simply encapsulated using quotes, so , becomes ",".
A command and quote needs to be encapsulated and quoted, so "," becomes """,""".
i have a small problem with my fwrite().
$txt=fopen("$directory","w");
if (($handle = fopen("$directory", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
$num = count($data);
...
...
There are no problem if i write:
fwrite($txt, "Hello;");
fwrite($txt, "Test fwrite;");
The output in the .csv file is like this:
Hello | Test fwrite
The problem appears when I have a variable contains the delimiter character, but I do not want fwrite consider it as a delimiter.
I have try to use chr(59), but the problem is not solved.
For example:
$var = "hello;test;hello;";
fwrite($txt, "Test fwrite;");
fwrite($txt, "$var;");
fwrite($txt, "Hello;");
The output of i would like to have is:
Test fwrite | hello;test;hello | Hello
Is possible do this without change the character delimiter ( ; )??
Thanks!
Easier done via fputcsv.
If your field contains the delimeter character you have to enclose the value (by default with double quotes).
e.g.
"abc;def";"x";"y";"z"
I'm importing a CSV using the fgetcsv() function, which is working all good.
However, when I take a look at the data in the database, I see black diamonds with question marks. This isn't too much of an issue when echoing the data back out again, as they don't appear, but when I want to use one of the CSV fields as a MySQL date, it isn't recognised as a date and is stored as 0000-00-00.
e.g.
I think this issue is something to do with encoding of the CSV? Can anyone offer any advice?
Thanks!
Edit: if it helps here is my import script, and the encode type is ASCII according to mb_detect_encoding
<?php
include 'config.php';
include 'opendb.php';
ini_set("auto_detect_line_endings", true);
$row = 0;
$tmpName = $_FILES['csv']['tmp_name'];
if (($handle = fopen($tmpName, "r")) !== FALSE) {
$num = count($data);
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
{
$noQuotes = str_replace("\"", '', $data);
$originalDate = $noQuotes[1];
//$delivery_date = date('Y-m-d', strtotime($originalDate));
$parts = explode('/', $originalDate);
$delivery_date = $parts[2] . '-' . $parts[1] . '-' . $parts[0];
$row++;
$import="INSERT into dispatch (delivery_note_number, delivery_date, dispatch_date, customer_delivery_date, delivery_line, produce, variety, quantity, pallets, count, depot, customer, grower, haulier, status)
values ('$noQuotes[0]', '$delivery_date', '$noQuotes[2]', '$noQuotes[3]', '$noQuotes[4]', '$noQuotes[5]', '$noQuotes[6]', '$noQuotes[7]', '$noQuotes[8]', '$noQuotes[9]', '$noQuotes[10]', '$noQuotes[11]', '$noQuotes[12]', '$noQuotes[13]', '$noQuotes[14]')";
echo $import;
mysql_query($import) or die(mysql_error());
}
//header("location:list_dispatch.php?st=recordsadded");
fclose($handle);
}
?>
If your database is using a different character encoding than the CSV file, it is possible the data should converted first.
One way to perform this is using the mb_convert_encoding() function.
Also useful, mb_detect_encoding() should be able to detect the character encoding for a given input string.
Someone found a solution on a another forum:
Those are NUL characters (ASCII code 0x00), replace them like this:
$string = str_replace(chr(0), '', $string);
fputcsv($f, $array, ' ', chr(0));
I have a file that looks like this:
1028806~HDR~20110815~15-AUG-2011~C~23:10~~~~~~~
1028806~DTL~C3914A~HWP-C3914A~1000949~A~LASERJET MAINT KIT 8100/N/DN~HEWLETT PACKARD~2659~12~0~0~475.75~658.75~0~3~Y~2~~2~475.75~5~~~009088336~~3179~10.60~N~8.25~8.50~20.50~~088698601976~44103109~6A~20030627~NNY~~A~S~~~~~~N~~~~~~20.50~8.50~8.25~~~~~~~~~~~~~~~~
1028806~DTL~70023301~OKI-70023301~1002121~A~OKILAN 6020E+ 10/100BASE-TX ETHERNET EXT~OKI PRINTING SOLUTIONS~2703~0~0~0~55.17~80.00~0~0~Y~0~~0~55.17~0~~~009117000~~2160~2.79~N~8.00~8.75~14.00~~000000180016~44101700~ACC-IMPACT~19950723~NNY~~A~S~~~~~~N~~~~~~14.00~8.75~8.00~~~~~~~~~~~~~~~~
1028806~DTL~PRO7T~APC-PRO7T~1003150~A~Professional-grade Protection for Computers and Electronics~AMERICAN POWER CONVERSION~20664~7~0~0~21.60~36.00~0~0~Y~0~~0~21.60~7~~~008112000~~4400~2.00~N~1.90~6.90~12.40~~731304000181~39121610~SURG~19950723~NNY~~A~S~~~~~~N~~~~~~12.40~6.90~1.90~~~~~~~~~~~~~~~~
1028806~DTL~PER7~APC-PER7~1003418~A~Surge suppressor ( external ) / 7 output connector(s)~AMERICAN POWER CONVERSION~20664~496~50~0~9.30~15.25~0~3~Y~86~~363~9.30~44~~~008118000~~4400~1.85~N~2.10~6.90~11.50~~731304000112~39121610~SURG~20011025~NNY~~A~S~~~~~~N~~~~~~11.50~6.90~2.10~~~~~~~~~~~~~~~~
1028806~DTL~PRO7~APC-PRO7~1003761~A~APC SurgeArrest Professional - Surge suppressor ( external ) - AC 120 V - 7 outp~AMERICAN POWER CONVERSION~20664~88~0~0~17.59~30.00~0~0~Y~12~~52~17.59~24~~~008112000~~4400~1.95~N~2.25~7.50~12.25~~731304000174~39121610~SURG~19950723~NNY~~A~S~~~~~~N~~~~~~12.25~7.50~2.25~~~~~~~~~~~~~~~~
I need to use a script to read certain parts of each line (the bold parts):
1028806~DTL~C3914A~HWP-C3914A~1000949~A~LASERJET MAINT KIT 8100/N/DN~HEWLETT PACKARD~2659~12~0~0~475.75~658.75~0~3~Y~2~~2~475.75~5~~~009088336~~3179~10.60~N~8.25~8.50~20.50~~088698601976~44103109~6A~20030627~NNY~~A~S~~~~~~N~~~~~~20.50~8.50~8.25~~~~~~~~~~~~~~~~
The file has over 300k items so going through manually is not an option, so how can I get a script to read only these parts when I don't know how long the part # and descriptions are? While ignoring all the other ~ characters.
Thanks
fgetcsv() can help here, a little more memory-conservative than loading the whole file up at once and explode()'ing all the lines into a giant array.
if (($handle = fopen("/path/to/file", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, "~")) !== FALSE) {
echo $data[2] . " " . $data[6];
}
}
fclose($handle);
Looks like you can explode on tilde:
$fields = explode('~', $line);
$part_num = $fields[2];
$desc = $fields[6];
// read the file
$lines = file('file.txt');
// loop through each line
foreach($lines as $line){
// separate the parts by the ~ delimiter up to the second bold part
// ignoring the rest of ~
$parts = explode('~', $line, 7);
echo $parts[2]; // output first bold part
echo $parts[6]; // output second bold part
}
I'm having a CSV like this.
john,joy, anna, Lucy Bravo,boy
I want to remove whitespace after ',' if it exist. And also make the first letter after ',' to be capital letter, if its not capital already. That is it should be like this:
John,Joy,Anna,Lucy Bravo,Boy
Only the whitespace after the ',' should go. I tried myself. But all failed. I hope PHP can solve this.
You could use regular expressions, but it's probably easiest to split it up into an array and operate on each entry:
function fix_entry($str) {
return ucfirst(ltrim($str));
}
$str = 'john,joy, anna, Lucy bravo,boy';
$fixed = implode(',', array_map(fix_entry, explode(',', $str)));
If you're opposed to making a function you could just use two array_maps, but that's up to you
Use trim() and ucfirst().
Here's a modified example from the documentation:
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
echo "<p> $num fields in line $row: <br /></p>\n";
$row++;
for ($c=0; $c < $num; $c++) {
echo ucfirst(trim($data[$c])) . "<br />\n";
}
}
fclose($handle);
}
Use str_getcsv to break the line into an array. Loop the array and use trim() or ltrim() and ucfirst() on each value.
http://us.php.net/manual/en/function.str-getcsv.php
http://us.php.net/manual/en/function.trim.php
http://us.php.net/manual/en/function.ltrim.php
http://us.php.net/manual/en/function.ucfirst.php