Substring each line of the string - php

inside my $result variable i have a 5 line string:
0100014746510106200140001020061780000000041666670072860103508101
0100008030950106200270002020139450000000020000006663540105338500
0100004586400106200270002020206660000000003700000511890102603900
0100008204530106200270002020218320000000011666670014450101008906
0100015309660106200270002021023010000000019400001666460105319807
how can i substr() each line... in order to have this result:
010001
010000
010000
010000
010001
in only need to get the first 6 columns of each line... please help...
PHP code:
$file = 'upload/filter.txt';
$searchfor = $_POST['search'];
$filename = $_POST['filename'];
$btn = $_POST['button'];
if($btn == 'GENERATE' ) {
//prevents the browser from parsing this as HTML.
//header('Content-Type: text/plain');
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");;
header("Content-Disposition: attachment;filename=".$filename.".txt ");
header("Content-Transfer-Encoding: binary ");
// get the file contents, assuming the file to be readable (and exist)
$contents = file_get_contents($file);
// escape special characters in the query
$pattern = preg_quote($searchfor, '/');
// finalise the regular expression, matching the whole line
$pattern = "/^.*$pattern.*\$/m";
// search, and store all matching occurences in $matches
if(preg_match_all($pattern, $contents, $matches)){
$result = implode("\n", $matches[0]);
echo $result;
}
else{
echo "No matches found";
}
}

Introducing strtok()
$text = <<<EOM
0100014746510106200140001020061780000000041666670072860103508101
0100008030950106200270002020139450000000020000006663540105338500
0100004586400106200270002020206660000000003700000511890102603900
0100008204530106200270002020218320000000011666670014450101008906
0100015309660106200270002021023010000000019400001666460105319807
EOM;
for ($line = strtok($text, "\n"); $line !== false; $line = strtok("\n")) {
echo substr($line, 0, 6), "\n";
}
The function strtok() chunks your string based on a token (or delimiter); in this code, each line is a chunk and for each chunk you only show the first six characters followed by a newline.
Update
You can also use preg_replace() like this:
echo preg_replace('/^(.{6}).*/m', '$1', $text);
It captures the first six characters, followed by the rest of the line; it then uses the memory capture to perform the replacement.

NOTE - Of all of the posted correct answers this is probably the most memory inefficient but hey, it's a one-liner.
Just to throw in a one-liner (will work on php 5.3 and above). This assumes your input is $str and lines will contain a newline separated string of the first 6 characters of each line.
$lines = implode("\n", array_map(function($a){return substr($a, 0, 6); }, explode("\n",$str)));

Code:
$str = "0100014746510106200140001020061780000000041666670072860103508101\n"
."0100008030950106200270002020139450000000020000006663540105338500\n"
."0100004586400106200270002020206660000000003700000511890102603900\n"
."0100008204530106200270002020218320000000011666670014450101008906\n"
."0100015309660106200270002021023010000000019400001666460105319807\n";
if( preg_match_all('#^\d{6}#m',$str,$matches) ){
echo join("\n",$matches[0]);
}
Result:
010001
010000
010000
010000
010001

basically:
$x=explode("\n",$result); //new line will depend on os ("\r\n"|"\r")
foreach($x as $line){
//substr $line
}

Try:
<?php
$str = explode(PHP_EOL, "
0100014746510106200140001020061780000000041666670072860103508101
0100008030950106200270002020139450000000020000006663540105338500
0100004586400106200270002020206660000000003700000511890102603900
0100008204530106200270002020218320000000011666670014450101008906
0100015309660106200270002021023010000000019400001666460105319807
");
for($i = 0; $i<count($str);$i++){
if($str[$i] != NULL)
echo substr((string)$str[$i],0,9);
}
?>
PHP_EOL =>
The correct 'End Of Line' symbol for this platform. Available since PHP 4.3.10 and PHP 5.0.2
PHP : Predefined Constants
You can also use '\r\n' if PHP_EOL is not available.

Related

How can I convert non-asciis to numbers in php?

I just started to code in php, and I got a task to do.
I have to read non-ascii characters like the " character from a file, convert them to a string array, the convert into integers,and add numbers to them.
For example, if I have the '"' character, I should get 147, then if I add -31 to it, it should return the character 't'.
Here is a code i tried;
$file = fopen("word.txt", "r") or die("File missing");
$wholefile=fread($file, filesize("word.txt"));
fclose($file);
$words =explode(chr(0x0A), $wholefile);
$file = fopen("password.txt", "r") or die("File missing");
$wholefile=fread($file, filesize("password.txt"));
fclose($file);
$words =explode(chr(0x0A), $wholefile);
//An exmaple
$str = $words[0];
for($i = 0; $i< strlen($str); $i++)
{
$str[$i] = chr(ord($str[$i]) - 31);
}
echo "$str";
Can you help me to get ascii characters isntead of ��-s?
The content of the file (exmaple)
pS“`nf2†ddn^MZrrŠ

PHP preg_replace - text will not be recognized

I have problems with preg_replace. The $insert_marker text will not be recognized and is caused by "$". If I remove the 2 $ characters, it works. So what is the problem?
function insert_into_file($file_path, $insert_marker, $text, $after = true) {
$contents = file_get_contents($file_path);
$new_contents = preg_replace($insert_marker, ($after) ? '$0' . $text : $text . '$0', $contents);
return file_put_contents($file_path, $new_contents);
}
$file_path = ".htaccess";
$insert_marker = "/##-- $Id: _.htaccess 10934 2017-08-31 12:11:28Z serpent_driver $/";
$text = "\n##added text";
$num_bytes = insert_into_file($file_path, $insert_marker, $text, true);
if ($num_bytes === false) {
echo "Could not insert into file $file_path.";
} else {
echo "Insert successful!";
}
$ is a special character for regex (it means end of line), you have to escape it: \$ and because you are using a variable that contains the regex and pass it as a parameter of the function, you have to triple escape:
$insert_marker = "/##-- \\\$Id: _.htaccess 10934 2017-08-31 12:11:28Z serpent_driver \\\$/";
It's a little hard to understand your question, but I figured out that you mean the $Id part of $insert_marker is causing issues. You need to escape the $ with a backslash, like so: $insert_marker = "/##-- \$Id: _.htaccess 10934 2017-08-31 12:11:28Z serpent_driver $/";

Get text on next line of value found PHP

I have the following text file called people.txt with the contents:
mikey.mcgurk
Boss Man
michelle.mcgurk
Boss Man 2
I'd like to adjust my PHP script to grab the data on the line that follows each username, so if I was searching for mikey.mcgurk, my script would output Boss Man.
PHP:
<?php //
$file = 'people.txt';
$searchfor = "mikey.mcgurk";
// the following line prevents the browser from parsing this as HTML.
header('Content-Type: text/plain');
// get the file contents, assuming the file to be readable (and exist)
$contents = file_get_contents($file);
// escape special characters in the query
$pattern = preg_quote($searchfor, '/');
// finalise the regular expression, matching the whole line
$pattern = "/^.*$pattern.*\$/m";
// search, and store all matching occurences in $matches
if(preg_match_all($pattern, $contents, $matches)){
// write all of this to a text file
echo implode("\n", $matches[0]);
}
else{
echo "No matches found";
}
you can do like this
$contents = file_get_contents($file);
$contents = explode(PHP_EOL, $contents);
if(array_search($searchfor, $contents) !== false){
echo $contents[array_search($searchfor, $contents)+1];
}
You can compare like this:
$contents = file_get_contents($file);
$lines = explode("\n",$contents);
for($i = 0; $i < count($lines); $i++) {
if( $lines[$i] ==$searchfor ) {
echo "Username ".$lines[$i+1];
}
}
Instead of using regular expression you can do this by getting all lines in an array
$lines = explode(PHP_EOL, $contents);
then get keys of results
$keys = array_keys($lines, $pattern);
and increment keys by 1 to get the next line
foreach ($keys as $key) {
echo $lines[++$key];
}

Avoid Line Repeat in PHP

I am working on a PHP code that reads data from text files and it searches for a certain word and echos it, for example, I search for
[Error]
Is it possible to only echo the word I search for only 1 time (aka if the word "Error" is found twice, only echo it once!)
$file = 'filesexample/'.$fileNameNew;
$searchfor = 'error';
header('Content-Type: text/plain');
$contents = file_get_contents($file);
$pattern = preg_quote($searchfor, '/');
$pattern = "/^.*$pattern.*\$/m";
if(preg_match_all($pattern, $contents, $matches)){
echo "Errors Found:\n";
echo implode("\n", $matches[0]);
}
Can I do this?
You can use the array_unique() PHP's function which remove duplicate values from an array:
if(preg_match_all($pattern, $contents, $matches))
{
$matches[0] = array_unique($matches[0]);
echo "Errors Found:\n";
echo implode("\n", $matches[0]);
}

Search only the first column of a text file

I have a text file with the following contents:
---> 12455 ---> 125 ---> KKK
---> 11366 ---> 120 ---> LLL
---> 12477 ---> 120 ---> YYY
I am using the following PHP code to search the file for "---> 124" and I get the following results:
---> 12455 ---> 125 ---> KKK
---> 12477 ---> 120 ---> YYY
but I want the results to be like this:
---> 12455
---> 12477
I want it to return only the first column.
<?php
$file = 'mytext.txt';
$searchfor = '---> ' . "124";
// the following line prevents the browser from parsing this as HTML.
header('Content-Type: text/plain');
// get the file contents, assuming the file to be readable (and exist)
$contents = file_get_contents($file);
// escape special characters in the query
$pattern = preg_quote($searchfor, '/');
// finalise the regular expression, matching the whole line
$pattern = "/^.*$pattern.*\$/m";
// search, and store all matching occurences in $matches
if(preg_match_all($pattern, $contents, $matches)) {
echo implode($matches[0]);
} else {
echo "No matches found";
}
?>
Change your approach a little bit. Instead of storing the search term and separator in a single string, use two variables.
$sep = '--->';
$searchfor = '124';
$pattern = "/^$sep\s+($searchfor\d+)\s+.*/m";
// search, and store all matching occurences in $matches
if(preg_match_all($pattern, $contents, $matches)){
echo implode(' ', $matches[1])."\n";
}
Outputs:
12455 12477
Demo.
First of all, seperate your concerns:
Read the file
Parse the content
Search
Using Iterators, you can achieve something great here but it will need a deeper understanding of OOP and the iterator interface. What i'll recommend is a simpler approach:
<?php
//Read the file line by line
$handle = fopen('file.txt', 'r');
while(!foef($handle)){
$content = fgets($handle);
//Parse the line
$content = explode('---> ', $content);
//Analyse the line
if($content[1] == 124){
echo $content[0]."\n";
}
}
fclose($handle);
That should be it, just adapt it as you see it, i haven't tested the code here!
change "/^.*$pattern.*\$/m" to "/$pattern\d*/i"
and then echo implode($matches[0]); to foreach($matches[0] as $item) echo "$item<br />\r\n";
If the structure is always as you have shown, then:
Read the file line by line;
explode(); each line by space  ;
Read the element [1] of the result;
This seems to be most logical to me. No need for regex in here, because it will work slower then simple explode operation.
Here is an example:
$handle = fopen( 'file.txt', 'r' );
if ( $handle ) {
while ( ( $line = fgets( $handle ) ) !== false ) {
$matches = explode( ' ', $line );
if ( $matches[4] == '124' )
echo $matches[1] . '<br/>';
}
}
try this:
--->\s\d{5}
regex is overkill here, a simple explode('--->', $str) and selecting the first element would suffice
$file = file_get_contents('file.txt');
$lines = explode('---> ', $file);
for($i=1; $i<count($lines); $i=$i+3)
if(strpos($lines[$i], '124')!==false)
$col[$i/3] = /*'--> ' . */$lines[$i];
print_r($col);
That seems to work just fine. Uncomment the comment above if you want the --> included in the output. Also, the resulting $col array is indexed with the row number it is found. Just replace [$i/3] with [] if you don't want that.
Furthering this:
function SearchFileByColumn($contents, $col_num, $search, $col_count = 3) {
$segs = explode('---> ', $contents);
for($i=$col_num; $i<count($segs); $i=$i+$col_count)
if(strpos($segs[$i], $search) !== false)
$res[] = $segs[$i];
return $res;
}
$results = SearchFileByColumn($contents, 1, '124');

Categories