I'm trying to just read even numbered lines from a text file. I know about the modulo(%) operator which I could put in a loop and attain the desired result, but somehow I can't figure out how to put it to use here.
Here is the code I have:
<?php
$url = "somedomain/something";
$lines = file('text.txt', FILE_IGNORE_NEW_LINES);
foreach ($lines as $line_num => $line) {
echo "<br />\n" . "Line #<b>{$line_num}</b> :" . (htmlspecialchars($line));
$dom = new DOMDocument;
$dom->loadHTMLFile($url . $line);
foreach ($dom->getElementsByTagName('p') as $node) {
// do stuff with $node
echo $node->nodeValue, "\n";
}
}
?>
Use the modulo operator on the line number. If it's 0 then the line is even, if it's 1 then the line is odd (these line numbers are zero-based -- swap them if you want one-based counting). Then use the continue statement to skip the rest of the loop body and go to the next line.
foreach ($lines as $line_num => $line) {
if ($line_num % 2 == 1) {
continue; // Skip odd lines
}
...
}
Try
if(!($line_num % 2)){
// your code
}
Related
My code is receiving a string which I have no control of, which I'll call $my_string. The string is the contents of a transcript. If I echo the string, like so:
echo $my_string;
I can see the contents, which look something like this.
1
00:00:00.000 --> 00:00:04.980
[MUSIC]
2
00:00:04.980 --> 00:00:08.120
Hi, my name is holl and I am here
to write some PHP.
3
00:00:08.120 --> 00:00:10.277
You can see my screen, here.
What I'd like to do is run this through a function so it's just the actual words spoken, removing all the lines that signify time, or the order.
[MUSIC]
Hi, my name is holl and I am here
to write some php.
You can see my screen, here.
My idea is to explode the whole string by the break, and try to detect which lines which are either empty or start with a number, like so...
$lines = explode("\n", $my_string);
foreach ($lines as $line) {
if (is_numeric(line[0]) || empty(line[0]) ) {
continue;
}
$exclude[] = $line;
}
$transcript = implode("\n", $exclude);
But the result of this action is exactly the same- the output has numbers and blank lines. I clearly misunderstand something- but what is it? And is there a better way of trying to achieve my goal?
Thanks!
EDIT: Removed an echo where I wasn't actually using one in my code.
The problem is that you use indexing on $line:
$lines = explode("\n", $my_string);
foreach ($lines as $line) {
if (is_numeric(line[0]) || empty(line[0]) ) {//index usage?
continue;
}
$exclude[] = $line;
}
$transcript = echo implode("\n", $exclude); //remove echo
replace by:
$lines = explode("\n", $my_string);
foreach ($lines as $line) {
if (is_numeric($line) || empty($line) ) {//here
continue;
}
$exclude[] = $line;
}
$transcript = implode("\n", $exclude);
You also need regex matching to remove the 00:00:00.000 --> 00:00:04.980 fragments.
You can combine them by:
if(preg_match('/^(|\d+|\d+:\d+:\d+\.\d+\s+-->\s+\d+:\d+:\d+\.\d+)$/',$line)) { //regex
takes all possibilities into account:
$lines = explode("\n", $my_string);
foreach ($lines as $line) {
if(preg_match('/^(|\d+|\d+:\d+:\d+\.\d+\s+-->\s+\d+:\d+:\d+\.\d+)$/',$line)) {
continue;
}
$exclude[] = $line;
}
$transcript = implode("\n", $exclude);
echo $transcript;
Example (with php -a):
$ php -a
php > $my_string='1
php ' 00:00:00.000 --> 00:00:04.980
php ' [MUSIC]
php '
php ' 2
php ' 00:00:04.980 --> 00:00:08.120
php ' Hi, my name is holl and I am here
php ' to write some PHP.
php '
php ' 3
php ' 00:00:08.120 --> 00:00:10.277
php ' You can see my screen, here.';
php > $lines = explode("\n", $my_string);
php > foreach ($lines as $line) {
php { if(preg_match('/^(|\d+|\d+:\d+:\d+\.\d+\s+-->\s+\d+:\d+:\d+\.\d+)$/',$line)) {
php { continue;
php { }
php { $exclude[] = $line;
php { }
php > $transcript = implode("\n", $exclude);
php > echo $transcript;
[MUSIC]
Hi, my name is holl and I am here
to write some PHP.
You can see my screen, here.
Your code works almost. Just forgot $ in line[0] and " " is not empty().
$my_string = <<< EOF
1
00:00:00.000 --> 00:00:04.980
[MUSIC]
2
00:00:04.980 --> 00:00:08.120
Hi, my name is holl and I am here
to write some PHP.
3
00:00:08.120 --> 00:00:10.277
You can see my screen, here.
EOF;
$lines = explode("\n", $my_string);
foreach ($lines as $line) {
$temp = trim($line[0]);
if (is_numeric($temp) || empty($temp) ) {
continue;
}
$exclude[] = $line;
}
$transcript = implode("\n", $exclude);
echo $transcript;
Result:
[MUSIC]
Hi, my name is holl and I am here
to write some PHP.
You can see my screen, here.
It looks like it's a pattern. That is every first and second line contain meta data, the third is text, and the fourth is empty. If that is indeed the case, it should be trivial. You don't have to check the content at all and just grab the third line of every quartet:
$lines = explode("\n", $my_string);
$texts = array();
for ($i = 0; $i < count($lines); $i++) {
if ($i % 4 == 2) { // Index of third line is 2, of course.
$texts[] = $lines[i];
}
}
$transcript = implode($texts, "\n");
With alternative logic, because as you rightfully mentioned there can be more than one line of text, you could say that blocks/entries whatever you call them, are separated by an empty line. Each block starts with two lines of meta data, followed by one (or maybe zero) or more lines of text. With that logic you could parse it like this:
$lines = explode("\n", $my_string);
$texts = array();
$linenr = 0;
foreach ($lines as $line) {
// Keep track of the how manieth non-empty line it is.
if ($line === '')
$linenr = 0;
else
$linenr++;
// Skip the first two lines of a block.
if ($linenr > 2)
$texts[] = $line;
}
$transcript = implode($texts, "\n");
I don't know this particular format, but if I wanted to do this, I would be eager to find a pattern like this rather than parse the lines themselves. It looks like a script or subtitle file, and if you want to turn it into a transcript, it would be a shame if somebody shouted '300' and it would not be transcripted.
to remove theses lines try to use : preg_replace + regex
php man [1]: http://php.net/manual/en/function.preg-replace.php
I am trying to only return the value of a <p> tag if it's not 0.
So far I've tried putting up a condition to check whether the value is not zero but no success
Example of what I'm trying to attain:
Line #0 :somecontent NOTZERO
Line #3 :somecontent NOTZERO
<?php
ini_set('max_execution_time', 300);
$url="http://somedomain/something/";
$lines = file('text.txt',FILE_IGNORE_NEW_LINES);
foreach ($lines as $line_num => $line){
if ($line_num % 2 == 1) {
continue; // Skip odd lines
}
echo "<br />\n"."Line #<b>{$line_num}</b> :" .(htmlspecialchars($line."\t"));
$dom = new DOMDocument;
$dom->loadHTMLFile($url.$line);
foreach ($dom->getElementsByTagName('p') as $node) {
// do stuff with $node
echo $node->nodeValue, "\n";
}
}
?>
Also, can you suggest me something to speed the execution?
It was simpler than I imagined. Hope someone finds this useful someday
<?php
ini_set('max_execution_time', 300000);
$url="http://somedomain/something/";
$lines = file('text.txt',FILE_IGNORE_NEW_LINES);
$i=0;
foreach ($lines as $line_num => $line){
if ($line_num % 2 == 1) {
continue; // Skip odd lines
}
$dom = new DOMDocument;
$dom->loadHTMLFile($url.$line);
foreach ($dom->getElementsByTagName('p') as $node) {
// do stuff with $node
if($node->nodeValue!="0"){
echo "<br />\n"."Line #<b>{$line_num}</b> :" .(htmlspecialchars($line."\t\t"));
echo $node->nodeValue, "\n";
}
}
}
?>
So I got the following function:
function searchWord($fileName, $str) {
$addthis = “string”;
$lines = file($fileName);
foreach ($lines as $lineNumber => $line) {
if (strpos($line, $str) !== false) {
$lines[$lineNumber] = $lines[$lineNumber].$addthis
file_put_contents($filename, implode($lines) . PHP_EOL);
break;
} else {
// do nothing
}
}
}
It searches for a specific string $str in a file $fileName. It then should add $addthis to the END (!!) of the line $lineNumber the $str was found on.
What the code does now is adding $addthis to the start of the line. I have searched the web but couldn't come up with a satisfying solution to my problem.
You need to remove the new line character from the end of your line before adding to it, then add a new line character back onto the end of it before writing back to the file. The updated line below should help.
$lines[$lineNumber] = trim($lines[$lineNumber]).$addthis.PHP_EOL;
Also, the write should happen after the loop.
Try this.
In my example, im using a text file called test.txt with these 3 lines on it:
apple
banana
cherry
Here's the PHP code.
<?php
// Search Function
function searchWord($fileName, $str, $addThis = 'string') {
if (file_exists($fileName)) {
$lines = file($fileName);
array_walk_recursive($lines, function(&$line) {
$line = trim($line);
});
foreach ($lines as $lineNo => $lineStr) {
if (false !== strpos($lineStr, $str)) {
$lines[$lineNo] = $lineStr . $addThis;
break;
}
}
file_put_contents($fileName, implode(PHP_EOL, $lines));
}
}
// Usage
searchWord('test.txt', 'banana', 'string');
?>
After the script is ran, the contents of test.txt is:
apple
bananastring
cherry
is this what you are after?
I would like to add a blank line at end of the last $member in below code to differentiate between each group. I have tried with below code
foreach($members as $key => $member)
{
$member = trim(preg_replace('/\s\s+/', ' ', $member));
$dev = " $member part of Form; <br>";
echo str_replace("<br>", "\r\n", $dev);
if($key == count($member)-0)
{
$space = "<br>";
echo str_replace("<br>", "\r\n", $space);
}
}
But It adding a blank space after each 2 line. How can I add space only at end of the last string ?
foreach($members as $key => $member)
{
$member = trim(preg_replace('/\s\s+/', ' ', $member));
$dev = " $member part of Form; <br>";
echo str_replace("<br>", "\r\n", $dev);
if($key == count($members)-1) <!--- ** check this line ---->
{
$space = "<br>";
echo str_replace("<br>", "\r\n", $space);
}
}
** You have counted the value of the key ($member) but actually it will be count of the original array ($members). Here $key starts from zero and it will end previous number of total array count.
I don't know your array structure of $members. You may use bellow code
$count = count($members);
$i = 1;
foreach($members as $key => $member)
{
$member = trim(preg_replace('/\s\s+/', ' ', $member));
$dev = " $member part of Form; <br>";
echo str_replace("<br>", "\r\n", $dev);
if($i == $count)
{
$space = "<br>";
echo str_replace("<br>", "\r\n", $space);
}
$i ++;
}
I'm not sure I understand what you're asking. If you want to add a newline after the last item, you can do so after the loop:
foreach ($members as $key => $member) {
# ...
}
echo "\r\n";
If you need it inside the loop, you will need to test for the last key. One way of doing this is by manipulating the array's internal pointer:
# Set internal pointer of array to the last entry:
end($members)
# Get the key of that last entry:
$lastKey = key($members)
foreach ($members as $key => $member) {
# ...
if ($key === $lastKey) {
echo "\r\n";
}
# ...
}
To add a newline "at the end of the last string", just echo it after the loop. But use the constant PHP_EOL instead of "\r\n".
Concatenating PHP_EOL to the end of each line will give you output that displays more or less the same in a browser and at the command line. Echoing one more PHP_EOL after the loop will insert a blank line that's visible from the command line, but not from the browser. If you need a blank line (more whitespace) in the browser, use CSS instead.
Since you seem to know how to replace <br> tags already, I ignored that part of your code. If you really need to replace those tags instead of just making your text more readable from the command line, you can easily do that.
$ cat code/php/test.php
<?php
$members = array(0 => 'Member0', 1 => 'Member1', 2 => 'Member2', 3 => 'Member3');
foreach($members as $key => $member)
{
$member = trim(preg_replace('/\s\s+/', ' ', $member));
echo " $member part of Form; <br>".PHP_EOL;
}
echo PHP_EOL;
?>
$ php code/php/test.php
Member0 part of Form; <br>
Member1 part of Form; <br>
Member2 part of Form; <br>
Member3 part of Form; <br>
$
$numItems = count($members);
$i = 0;
foreach($members as $key=>$member) {
if(++$i === $numItems) {
$space = "<br">;
echo str_replace("<br>", "\r\n", $space);
}
}
Find the last element of an array while using a foreach loop in PHP
I have a problem where i have a script that supposed to search an XML file for matching strings.
Here's my script:
<?php
$file = "klein.xml";
$lines = file($file);
foreach ($lines as $line_num => $line)
{
echo htmlentities($line);
echo "<br>";
}
if (preg_match("/message/", htmlentities($line), $found))
{
echo "Found!";
echo $found[0];
echo "test";
}
else
{
echo "Not Found!";
}
?>
and this is the xml file im working with:
<?xml version="1.0" encoding="ISO-8859-1"?>
<product-data>
<message-header>
<message-id>OR-1361163557-gr</message-id>
<message-timestamp>1361163557</message-timestamp>
<export-version current_version="1">OGPDX-2.01.01</export-version>
</message-header>
</product-data>
The problem is when i preg match 'product' it works correctly but when i try to preg match another string i.e 'message' it doesnt work?
Im curious for the solution, thanks in advance!
Can you check this code, I noticed that you put the if loop outside foreach; hence only the last line is executed.
<?php
$file = "klein.xml";
$lines = file($file);
foreach ($lines as $line_num => $line)
{
if (preg_match("/message/", htmlentities($line), $found))
{
echo "Found ".$found[0]."<br />";
}
}
?>
the problem is with your logic: you are only checking the last value of $line which is contain </product-data>
so what are you searching in? a line of your xml ...
when you are searching "product" (in last line) $line is in last line .
foreach ($lines as $line_num => $line)
{
if (preg_match("/message/", $line , $found))
{
echo "Line: $line_num - ".$found[0]." <br>";
}
}