Extract certain data from a text file and create a table [closed] - php

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Hi I am very new on PHP programming i am just trying to learn a little bit more on how can i work with files.
I having a text file with some bunch of data like below.
image from the file
Policy Name: TU_TOPS_VM-Full_30D_00_2
Daily Windows:
Saturday 19:50:00 --> Sunday 06:00:00
Policy Name: TU_QW_VM-FULL_30D_18_01
Daily Windows:
Sunday 02:05:00 --> Sunday 09:00:00
Policy Name: TU_GPAS_FULL-VM_30D_18_01
Daily Windows:
Friday 22:00:00 --> Saturday 06:00:00
I would like to have an output similar to this in a table.
POlicy Day Time
TU_TOPS_VM-Full_30D_00_2 Saturday Saturday 19:50:00
TU_QW_VM-FULL_30D_18_01 Sunday 02:05:00
TU_GPAS_FULL-VM_30D_18_01 Friday 22:00:00
From my code i was able to obtain the Policy name and organize the data in a table column.
Output from code.
POlicy Day Time
TU_TOPS_VM-Full_30D_00_2
TU_QW_VM-FULL_30D_18_01
What i was able to do so far.
<?php
$lines= file('schedule');
$lines = preg_grep("/Policy Name:/", $lines);
echo'
<table>
<tr>
<td>POlicy</td>
<td>Day</td>
<td>Time</td>
</tr>';
foreach ($lines as $policy) {
$find="Policy Name:";
$replace="";
$po= (str_replace($find,$replace,$policy));
echo '
<tr>
<td>'.$po.'<br></td>
</tr>
</table>';
}
?>
How can i extract the day and time and organize it beside the policy
name?.

You're throwing away the other lines when you use preg_grep. Instead, loop over all the lines, checking which kind of line it is.
Also, </table> should not be inside the loop, it should only be at the end of the loop.
<?php
$lines= file('schedule', FILE_IGNORE_NEW_LINE);
echo'
<table>
<tr>
<td>POlicy</td>
<td>Day</td>
<td>Time</td>
</tr>';
foreach ($lines as $line) {
if (strstr($line, 'Policy Name:')) {
$policy = str_replace('Policy Name:', '', $line);
} elseif (preg_match('/(\w+)\s+(\d\d:\d\d:\d\d)\s+-->/', $line, $match)) {
$day = $match[1];
$time = $match[2];
echo "
<tr>
<td>$policy</td>
<td>$day</td>
<td>$time</td>
</tr>";
}
}
echo "\n</table>";
?>

#Barmar wrote a great answer. Here's a different tack, in that I want to control where my array breaks (i.e. not at each line, because I'm not sure where your line breaks are). Also, less specific matching gives you more support for variability in your input (which may not be an issue for you).
<?php
$string = file_get_contents('schedule') ; // read the file in as a string, not an array
$text_array = explode("Policy Name:", $string) ; // break the string into an array of strings at each "Policy Name:"
foreach($text_array as $entry){
$entry = preg_replace('/\s+/', ' ',$entry) ; // conflate whitespace into a single space for delimiting
$sub_entry_array = explode(' ', $entry) ; // split each substring into an array
$table_rows .= "<tr><td>$sub_entry_array[1]</td><td>$sub_entry_array[4]</td><td>$sub_entry_array[5]</td></tr>" ; // display the array values we want
}
echo "<table><tr><th>Policy</th><th>Day</th><th>Time</th></tr>$table_rows</table>" ;
?>

Related

How can I split a PHP code so that it shows me the results from a text file one under the other? [duplicate]

This question already has answers here:
explode single variable in php
(4 answers)
Closed 1 year ago.
<?php
$q = $_REQUEST["q"];
$f = fopen("fence.txt", "r");
while (($line = fgets($f)) !== FALSE) {
if (strstr($line, $q)) {
echo "<li>Your Card Number and Expiration Date: $line";
} // outputs card+expiration date if either one is found in the line
}
?>
I have this code where it takes the input from the user, their card number, and displays that card alongside the expiration date for it.
The code takes the Card numbers and dates from fence.txt.
The data inside of fence.txt shows up as
123456,7/4/2023
111399,4/7/2021
213262,11/13/2030
213268,11/13/2030
When the user searches for card 123456 the result is as follows
Your Card Number and Expiration Date: 123456, 7/4/2023
I've been trying to figure out how I can make it so that it shows up as
Your Card Number: 123456
Expiration Date: 7/4/2023
I've been trying to explode it, but it hasn't worked. What can I do to it? I also want it to say "Not Found" if the card isn't found in the file.
Please try this:
$res = explode(',', $line);
echo "Your Card Number:". $res[0] ."<br> Expiration Date:". $res[1];

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>

How to count complete sets of items in php? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I am a newbie, so hopefully I word this properly. I have searched and searched both SO and the web to try to find this answer, even mathematically, to understand how to code it, but to no avail.
On a web game, I want to be able to count the number of complete sets a user has (the set has four items).
For example, the user can attain turkey, pumpkin pie, stuffing, and mashed potatoes. Those are displayed in a table by quantity, like so:
Mashed Potatoes: 2
Turkey: 4
Pumpkin Pie: 4
Stuffing: 3
So in this case, the user has 2 total sets of what I'll call a "Thanksgiving Dinner." The Thanksgiving Dinner must include one of each item to be a complete set.
How can I use PHP to count and display the number of complete sets the user has?
This feels like it should be so simple (mathematically, at least), but I am really struggling.
Try this, simple, as shown in this PHP Fiddle
<?php
$min = 100000; // just initialize min with large value.
// these values can be hard coded, from JSON, html form, or database
// it is just written for illustration
$arr = array(
'Mashed Potatoes' => 2,
'Turkey' => 4,
'Pumpkin Pie'=> 4,
'Stuffing'=> 3
);
// we loop through each element of the above array and,
// compare its value to the min.
foreach($arr as $value){
if( $value < $min){
// If the value is less that min. then we store value into min
$min = $value;
}
}
echo 'You can have ' . $min . ' Thanksgiving dinners';
?>
EDIT:
As suggested in a comment from PaparazzoKi, Thanks, you can replace all of this:
foreach($arr as $value){
if( $value < $min){
// If the value is less that min. then we store value into min
$min = $value;
}
}
echo 'You can have ' . $min . ' Thanksgiving dinners';
With this line:
echo 'You can have ' . min($arr) . ' Thanksgiving dinners';
Making use of the .min() function
The total number of complete set will the the key with the lowest value in the array.
You may use the min() function of PHP
http://php.net/manual/en/function.min.php

How to echo out the contents of text files in a directory based on the date that it was last modified?

I have created a directory with the following files located within:
index.php
one.txt - Hello
two.txt - Ok
three.txt - Goodbye
four.txt - Cool
Everything in bold tells you what those text files contain.
What I am trying to do is echo out all of the contents of the text files into the index.php page. So when the user visits the index.php page, this is what they'll see:
Date: 13 May 2015 Contents of text file: Hello
Date: 12 May 2015 Contents of text file: Ok
Date: 11 May 2015 Contents of text file: Goodbye
Date: 10 May 2015 Contents of text file: Cool
As you can see from above, the date the text files were created along with its contents are all echoed out. Also, they are echoed out based on the order that they were last modified.
This is the code that I am trying to use to achieve this:
<?php
foreach (glob("*.txt") as $filename) {
echo "Date:";
echo date('d F Y', filemtime($filename)) .
"Contents of text file:";
echo file_get_contents($filename);
}
?>
What's happening in this code is that:
All of the text files in the directory are picked up
For each text file, it gets its last modification date and what it contains echoed out
The outcome of this code is that it is similar to what can be seen in the yellow box above (which is what I am trying to achieve) however the order of the echo is not in date order. It gets echoed out a little something like this:
13 May
10 May
11 May
12 May
How would I make it so that it gets echoed out based on the date that it was last modified? With the latest date at the top and the oldest date at the bottom?
Do this:
<?php
foreach (glob("*.txt") as $filename) {
$result[date('Ymd', filemtime($filename))]=
"Date:".
date('d F Y', filemtime($filename)) .
"Contents of text file:".
file_get_contents($filename);
}
ksort($result);
echo implode("", $result);
?>
<?php
foreach (glob("*.txt") as $filename)
{
$time = filemtime($filename);
$files[$filename] = $time;
}
arsort($files);
foreach ($files as $file => $time)
{
"Contents of text file:";
echo file_get_contents($file);
}
?>
Edit:
Thanks Glavić for the hint. I updated the script, so files don't get lost.

PHP Integers with leading zeros

Particularly, 08 and 09 have caused me some major trouble. Is this a PHP bug?
Explanation:
I have a calendar 'widget' on a couple of our client's sites, where we have a HTML hard-coded calendar (I know a PHP function can generate n number of months, but the boss man said 'no').
Within each day, there is a PHP function to check for events on that day, passing the current day of the month like so:
<td valign="top">01<?php printShowLink(01, $events) ?></td>
$events is an array of all events on that month, and the function checks if an event is on that day:
function printShowLink($dayOfMonth, $eventsArray) {
$show = array();
$printedEvent = array();
$daysWithEvents = array();
foreach($eventsArray as $event) {
if($dayOfMonth == $event['day'] && !in_array($event['id'], $printedEvent)){
if(in_array($event['day'], $daysWithEvents)) {
echo '<hr class="calendarLine" />';
} else {
echo '<br />';
}
$daysWithEvents[] = $event['day']; // string parsed from timestamp
if($event['linked'] != 1) {
echo '<div class="center cal_event '.$event['class'].'" id="center"><span title="'.$event['title'].'" style="color:#666666;">'.$event['shorttitle'].'</span></div>';
$printedEvent[] = $event['id'];
} else {
echo '<div class="center cal_event '.$event['class'].'" id="center">'.$event['shorttitle'].'</div>';
$printedEvent[] = $event['id'];
}
}
}
}
On the 8th and 9th, no events will show up. Passing a string of the day instead of a zero-padded integer causes the same problem.
The solution is as what is should have been in the first place, a non-padded integer. However, my question is, have you seen this odd behavior with 08 and/or 09?
I googled this and couldn't find anything out there.
Quote it. 0123 without quotes is octal in PHP. It's in the docs
$ php -r 'echo 01234, "\n01234\n";'
668
01234
$
So you should change your code to
<td valign="top">01<?php printShowLink('01', $events) ?></td>
It's been a while since I've had to wade through so much PHP been doing mostly Javascript for 3 years. But 08 and 09 being a problem makes me think: they could be getting treated as octal (base 8), and the digits 8 and 9 do not exist in octal.

Categories