match data from row to another row in csv file using php? - php

I am newbie in php. Can this be possible to be done?? the script role is to find the match in another row but not on the same column...
the .csv file
**first row** **second row** **third row**
This is for NNMM NN/MM#000-45NNMM;1 2001
AA/BB#000-45AABB;2 ----- 2002
NN/MM#000-45NNMM;2 ----- 2003
This is for XXYY XX/YY#000-45XXYY;1 2004
LL/QQ#000-45LLQQ;2 ----- 2005
WW/KK#000-45WWKK;2 ----- 2006
CC/DD#000-45CCDD;2 ----- 2005
PP/SS#000-45PPSS;2 ----- 2006
This is for AABB AA/BB#000-45AABB;1 2007
XX/YY#000-45XXYY;2 ----- 2008
This is for PPSS PP/SS#000-45PPSS;1 2009
This is for CCDD CC/DD#000-45CCDD;1 2010
in first row: there are 5 fields the last char in string is "2".(i.e.AA/BB#000-45AABB;2)
in second row: there are 5 fields the last char in string is "1".(i.e.AA/BB#000-45AABB;1)
now i want to do a matching script where the first row find the match in 2ndrow.. and display the data from first row which the match is found... hope it makes sense...
desired output
This is for NNMM NN/MM#000-45NNMM;1 2001
This is for XXYY XX/YY#000-45XXYY;1 2004
This is for AABB AA/BB#000-45AABB;1 2007
This is for PPSS PP/SS#000-45PPSS;1 2009
This is for CCDD CC/DD#000-45CCDD;1 2010
i have started a script but stuck working out with the logic...
$file = fopen('sample.csv', 'r');
echo "<table style='border: 2px solid black; text-align:left'>";
while (($line = fgetcsv($file)) !== FALSE) {
list( $row1, $row2, $row3) = $line;
echo "<tr>";
echo "<td>$row1</td>";
echo"<td>$row2</td>";
echo "<td>$row3</td>";
echo "</tr>";
}
echo "</table>";

It is propably not best tool for that, but I tried to do it with regex, and I know it is ugly, but try it out:
(?|(?:([A-Z]{2}\/[A-Z]{2}#\d{3}-\d{2}([A-Z]{4});)(1))(?=(?:.|\n)+?(\d{4})(?:.|\n)+\1(?:2))|(?:([A-Z]{2}\/[A-Z]{2}#\d{3}-\d{2}([A-Z]{4});)2)(?=(?:.|\n)+(?:\1(1))(?:.|n)+?(\d{4})))
DEMO
Relevant data is in groups, so you can use something like: "This is for $2\t$1$3\t$4" to get data you want. In substitution part of my demo, you can see the output (but it only replace matched parts and the the rest of umatched text is still there, but it is just to see how such output could look).

use a do while() instead of while sorry can't write the code for you
and you have to use if statements also if ($row1 == $row1) {then do this}

Related

Transposing csv values in php

I need to transpose some values in some csv files that we get sent on a regular basis so that they are able to be imported into a website and I'm not sure the best way to go about doing it.
The data arrives in a csv file with a header row containing the column names, and the first column values are product ID's. The data looks like this…
ID F F-VF VF VF-XF XF
1 840 960 1080 1248 1944
2 1137.5 1300 1462.5 1690 2632.5
3 1225 1400 1575 1820 2835
What I'm looking to do is change this around so the column name and it's value are put into a new line for each value for the same id like so…
ID COND VALUE
1 F 840
1 F-VF 960
1 VF 1080
1 VF-XF 1248
1 XF 1944
2 F 1137.5
2 F-VF 1300
2 VF 1462.5
2 VF-XF 1690
2 XF 2835
I may also need to add some strings into the cells - is that easy to do?
Thanks a lot
Not necessarily the most elegant version, just to get an idea.
Something like this would work in case it's a existing csv, which gets read and overwritten with the transposed version.
// assuming a dataset like
// ----
// fruit, apple, pear, peach
// animal, eagle, bear, wolf
// car, renault, fiat, nio
$f = fopen($savePath, 'r');
$header = [];
$data = [];
while($row = fgetcsv($f, 0, ",")) {
$header[]=$row[0];
for ($i = 1; $i < sizeof(array_keys($row)); $i++) {
$data[$i][$row[0]]=$row[$i];
}
}
fclose($f);
$f = fopen($savePath, 'w');
fputcsv($f, $header);
foreach ($data as $recordColDataSet) {
fputcsv($f, array_values($recordColDataSet));
}
fclose($f);
Transposing arrays could also be something to look at eg in this question here:
Transposing multidimensional arrays in PHP
Have you tried any of the standard PHP methods like: str_getcsv() or fgetcsv()?
A quick search of "php csv" provides a TON of possible solutions. I suggest trying a few, then reporting back here if you have a specific problem.

Need some assistence with Regex (PHP)

I'd like to parse txt files to HTML using preg_replace to add formatting.
The format of the file is like this :
09:19:49 13-12-15 Sunday Hello World
1234567 Today is a beautiful day
1234568 Tomorrow will be even better
1234569 December is the best month of the year!
This should be treated as a group and parsed into a table, like :
<table>
<tr><td>09:19:49 13-12-15</td><td>Sunday</td><td>Hello World</td></tr>
<tr><td>1234567</td><td>(optional)</td><td>Today is a beautiful day</td></tr>
<tr><td>1234568</td><td>(optional)</td><td>Tomorrow will be even better</td></tr>
<tr><td>1234569</td><td>(optional)</td><td>December is the best month of the year!</td></tr>
</table>
For now, I'm using two separate preg_replacements, one for the first line (date) and a second one for the following ones, which can be just one or up to 100 or so. But, this file can contain other text as well, which needs to be ignored (as for the replacement), but if this line has more or less the same format (7 digits and some text) it gets formatted as well :
$file = preg_replace('~^\s*((\[.*\]){0,2}\d{1,2}:\d{2}:\d{2}(\[/.*\]){0,2})\s(\d{2}-\d{2}-\d{2}(\[/.*\]){0,2})\s+(?:\d{2}/\d{3}\s+|)(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)\s+(.+)$~m', '<table class="file"><tr class="entry"><td class="time">$1 $4</td><td class="day">$6</td><td class="message">$7</td></tr>', $file);
$file = preg_replace('~^\s*(.{0,11}?)\s*((\[.+?\])?\d{7}(\[/.+?\])?)\s+(.+?)$~m', '<tr class="id"><td class="optional">$1</td><td class="id">$2</td><td class="message">$5</td></tr>', $file);
How to improve this? Like, if I have this content :
09:19:49 13-12-15 Sunday Hello World
1234567 Today is a beautiful day
1234568 Tomorrow will be even better
1234569 December is the best month of the year!
Liverpool - WBA 2-2
1234570 This line should be ignored
19:29:59 13-12-15 Sunday Hello World
1234571 Today is a beautiful day
1234572 Tomorrow will be even better
So, I'd like to catch and preg_replace only the first block and the last one, starting with time/date and some following lines, starting with a 7-digit ID.
So far, thanks for reading ;)
I think this accomplishes what you are trying to do.
There was one line that were unclear to me why it should be ignored:
1234570 This line should be ignored
This line meets the 7 digits and some text requirement.
The regex I came up with was:
/^(\d{2}:\d{2}:\d{2}\h*\d{1,2}-\d{1,2}-\d{1,2}|\d{7})\h*([a-zA-Z]{3}day)?\h*(.+)/m
Here is a regex101 demo: https://regex101.com/r/qB0gH6/1
and in PHP usage:
$string = '09:19:49 13-12-15 Sunday Hello World
1234567 Today is a beautiful day
1234568 Tomorrow will be even better
1234569 December is the best month of the year!
Liverpool - WBA 2-2
1234570 This line should be ignored
19:29:59 13-12-15 Sunday Hello World
1234571 Today is a beautiful day
1234572 Tomorrow will be even better';
echo preg_replace('/^(\d{2}:\d{2}:\d{2}\h*\d{1,2}-\d{1,2}-\d{1,2}|\d{7})\h*([a-zA-Z]{3}day)?\h*(.+)/m', '<td>$1</td><td>$2</td><td>$3</td>', $string);
Output:
<td>09:19:49 13-12-15</td><td>Sunday</td><td>Hello World</td>
<td>1234567</td><td></td><td>Today is a beautiful day</td>
<td>1234568</td><td></td><td>Tomorrow will be even better</td>
<td>1234569</td><td></td><td>December is the best month of the year!</td>
Liverpool - WBA 2-2
<td>1234570</td><td></td><td>This line should be ignored</td>
<td>19:29:59 13-12-15</td><td>Sunday</td><td>Hello World</td>
<td>1234571</td><td></td><td>Today is a beautiful day</td>
<td>1234572</td><td></td><td>Tomorrow will be even better</td>
Okay, per your update it is a bit more complicated but I think this does it:
$string = '09:19:49 13-12-15 Sunday Hello World
1234567 Today is a beautiful day
1234568 Tomorrow will be even better
1234569 December is the best month of the year!
Liverpool - WBA 2-2
1234570 This line should be ignored
19:29:59 13-12-15 Sunday Hello World
1234571 Today is a beautiful day
1234572 Tomorrow will be even better';
echo preg_replace_callback('/(?:^|\n)(\d{2}:\d{2}:\d{2}\h*\d{1,2}-\d{1,2}-\d{1,2})\h+([a-zA-Z]{3}day)?\h*(.+?)\n((\d{7})\h+(.+?)(\n|$))+/',
function ($matches) {
$lines = explode("\n", $matches[0]);
$theoutput = '<table><tr>';
foreach($lines as $line) {
if(preg_match('/(?:^|\n)(\d{2}:\d{2}:\d{2}\h*\d{1,2}-\d{1,2}-\d{1,2})\h+([a-zA-Z]{3}day)?\h*(.*)/', $line, $output)) {
//it is the first date string line;
foreach($output as $key => $values) {
if(!empty($key)) {
$theoutput .= '<td>' . $values . '</td>';
}
}
} else {
if(preg_match('/(\d{7})\h*(.*)/', $line, $output)) {
$theoutput .= '</tr><tr>';
foreach($output as $key => $values) {
if(!empty($key)) {
$theoutput .= '<td>' . $values . '</td>';
}
}
}
}
}
$theoutput .= '</tr></table>';
return $theoutput;
}, $string);
Output:
<table><tr><td>09:19:49 13-12-15</td><td>Sunday</td><td>Hello World</td></tr><tr><td>1234567</td><td>Today is a beautiful day</td></tr><tr><td>1234568</td><td>Tomorrow will be even better</td></tr><tr><td>1234569</td><td>December is the best month of the year!</td></tr></table>
Liverpool - WBA 2-2
1234570 This line should be ignored
<table><tr><td>19:29:59 13-12-15</td><td>Sunday</td><td>Hello World</td></tr><tr><td>1234571</td><td>Today is a beautiful day</td></tr><tr><td>1234572</td><td>Tomorrow will be even better</td></tr></table>

Array size in PHP shown as one despite of having more elements

Following is my code which I am using for testing purposes so far. I have to use it further in my project.
It access a certain web service and retrieves data as xml. XML is brought to $arr array.
Address of $url and 3rd parameter in client->call() are not mentioned on purpose.
$url = "";
$client= new nusoap_client($url);
$param = array("status"=>"p2");
$arr = $client->call('getAllVisitByStatus',$param,'');
echo $arr."\n";
$size = sizeof($arr);
echo $size;
for($num=0; $num<986; ++$num)
{
echo $arr[$num], "\n";
if($arr[$num] == '>')
{
echo "<br/> ";
}
}
If I save the data returned by client->call() into an array and print it with a loop then it prints the XML like this
<?xml version = "1.0" encoding = "UTF - 8" standalone = "yes" ?>
<lists>
<visitW>
<followup> 2015 - 01 - 30 00:50:00.0 </followup>
<person_id> 12 </person_id>
<remarks> nothing </remarks>
<treatment> doing </treatment>
<visit_date> 2015 - 01 - 04 - 00 - 24 - </visit_date>
<visit_id> 4 </visit_id>
<visit_type> Hesschart</visit_type>
</visitW>
</lists>
However, if take $arr as a string, it prints this:
2015-01-30 00:50:00.0 12 nothing doing 2015-01-04-00-24- 4 Hesschart
So, in a string it prints without tags and like this.
The problem is that when the size of array is printed, it prints 1. However, the array contains the whole XML brought as a result of service call.
When I use a loop of exact number of elements i.e. 986, then it prints the whole XML as it is.
The question is that why does it show 1 as the size of the array? Also, can this array containing XML be put in DOM Parser?

Need help within a loop to group data

Need some help, been going around this for ages, but just cant seem to solve it. I've got some data in a field called "Term Year PrNo". The data in this field is like below:
[2010-201110]Winter - 2010 - 1st
[2010-201111]Winter - 2010 - 2nd
[2010-201120]Spring - 2011 - 1st
[2010-201121]Spring - 2011 - 2nd
[2010-201130]Summer - 2011 - 1st
[2010-201131]Summer - 2011 - 2nd
[2011-201210]Winter - 2011 - 1st
[2011-201211]Winter - 2011 - 2nd
[2011-201220]Spring - 2012 - 1st
[2011-201221]Spring - 2012 - 2nd
[2011-201230]Summer - 2012 - 1st
[2011-201231]Summer - 2012 - 2nd
[2012-201310]Winter - 2012 - 1st
[2012-201311]Winter - 2012 - 2nd
[2012-201320]Spring - 2013 - 1st
[2012-201321]Spring - 2013 - 2nd
[2012-201330]Summer - 2013 - 1st
I need to make each row of data in that field a radio button selection, which I've managed to do by sticking the contents of the field and spitting it out as an input field. I've also used regex to clean the look of the input value - i.e. remove the first sort field. So far so good. The problem I cant seem to solve is I need to break the data down in segments and wrap them around a div class called yearblock based on the years, 2010-2011 | 2011-2012 | 2012-2013, so that I can arrange them nicely using CSS. I've managed to figure out how to start div class, by comparing previous year to current year, but I cant seem to figure out how to appropriately put the end in after echoing out my input. Hope this makes sense, can someone look at my code and point me in the right direction please?
<?php
$arrayTermdates = array();
foreach($termsResult->getRecords() as $key => $term)
{
$arrayTermdates[] = $term->getField('Term Year PrNo');
}
$arrayTermdates = array_unique($arrayTermdates);
sort($arrayTermdates, SORT_STRING | SORT_FLAG_CASE);
foreach($arrayTermdates as $termdate)
{
preg_match_all("/\[[^)]+\]/",$termdate,$matches);
$year = str_replace('[', '', $matches[0][0]);
$year = str_replace(']', '', $year);
$year = str_replace(' ', '', substr($year, 0, -2));
$termdate = preg_replace("/\[[^)]+\]/","",$termdate);
/*
/ - opening delimiter (necessary for regular expressions, can be any character that doesn't appear in the regular expression
\[ - Match an opening parenthesis
[^)]+ - Match 1 or more character that is not a closing parenthesis
\] - Match a closing parenthesis
/ - Closing delimiter
*/
if ($previousYear != $year || $previousYear == '')
{
echo '<div class="yearblock">';
echo '<strong>'.$year.'</strong><br />';
}
?>
<div class="term_value_list">
<input name="Termdate[]" type="radio" value="<?php echo $termdate; ?>">
<?php
$TermdatesArray = explode('-',$termdate);
$Termdisplay = $TermdatesArray[0].' '.$TermdatesArray[1].' ['.str_replace(' ', '', $TermdatesArray[2]).' PR]';
echo $Termdisplay;
?>
<!-- I need to echo an </div> for div class yearblock -->
You're almost there. I'm going to make a little simplification to your code to get rid of the regexp, however.
First off, we are going to initiate a year tracker. This will allow us to keep track of which year we are in.
$myCurrentYear = false;
From there, we'll loop through your rows. The first check we will do is to check if the year is different. If it is, and the current year was not false, we'll output a </div>. Then, if it was different, we'll print headers for the new year.
foreach ($arrayTermdates as $date) {
$newdate = split("-",substr($date,strpos($date,"]")+1));
// Gotta remember to trim stuff
$year = (int)trim($newdate[1]);
if ($year != $myCurrentYear) {
if ($myCurrentYear !== false) {
echo "</div>";
}
$myCurrentYear = $year;
echo "<div class='yearblock'><strong>Year ".$myCurrentYear."-".($myCurrentYear+1)."</strong>:";
}
// Do your processing here
}
// NOTE: the last one won't be closed. We'll close it here
if ($myCurrentYear !== false) {
echo "</div>";
}
Start your first div before the first output:
echo '<div class="yearblock">';
Then close the block and open a new one each time your if() condition is true:
if ($previousYear != $year || $previousYear == '')
{
echo '</div><div class="yearblock">';
echo '<strong>'.$year.'</strong><br />';
}
And finally, close the final div after you have finished creating output:
echo '</div>';

create parent child array from inline data in php

actually i have simple problem but i forget how to solve it.. :D
i have data on table with following format
01 Johson 01 Craig
01 Johson 02 Daniel
01 Johson 03 Abbey
02 Dawson 01 Brown
02 Dawson 02 Agust
03 Brick 01 Chev
03 Brick 01 Flinch
so i want it to become an array like this
01 Johson => 01 Craig
``````````````02 Daniel
```````````````03 Abey
`
etc...
how to iterate trough the data and make it array like that...
i'm newby in PHP :))
There are a number of ways to get the outcome, though I am partial to using a mysql group concat:
select
col1,
group_concat(col2) as col2
from
tableName
group by
col1;
This will return that particular column of data in a comma delimted string, which you can then very easily explode inside your PHP code as it comes from the database.
Even though a comma is the default for group_concat, you can easily change it to concat the rows of data on a different string as well.
Is this what you want?
$results = array();
while ($row = mysqli_fetch_assoc($query_result)) {
$parent = $row['parentid'].' '.$row['parentname'];
if (!array_key_exists($parent, $results)) {
$results[$parent] = array();
}
$results[$parent][] = $row['childid'].' '.$row['childname'];
}

Categories