help using php explode () and organizing output - php

Can someone pls show me how to map this correctly? I am trying to understand how to use php explode() and organizing the values in a way that I can retrieve and print them in some organized matter. For each record I want to put a name=value in a particular bucket. I have (7) max buckets per record. Sometimes I have records that won't fill each bucket.
(for example record (2) is missing attributes (5,6,7) and record (3) is missing attribute (4)).
1-Column=host1.colo.sub;2-Column=Fri Aug 13;3-Column=db9.nfl.colo2.;4-Column=00:00:03;5-Column=01:55:02;6-Column=87.24 MB;7-Column=Success;
1-Column=host1.colo.sub;2-Column=Fri Aug 13;3-Column=pdb2.colo2.;4-Column=04:00:02;
1-Column=host1.colo.sub;2-Column=Fri Aug 13;3-Column=gl3_lvm;5-Column=04:48:06;6-Column=54.64 MB;7-Column=Success;
So far I wrote this to view my output:
<?php
$InputFile = file("test.txt");
foreach ($InputFile as $line){
$pieces = explode(";", $line);
//print $pieces[0];
//print $pieces[1];
//print $pieces[2];
print $pieces[3];
//print $pieces[4];
//print $pieces[5];
//print $pieces[6];
//print_r($line);
}
?>
I would like to print out similar values for each attribute instead of this where its mixed.
Using 'print $pieces[3];'
4-Column=00:00:034-Column=04:00:025-Column=04:48:06

$InputFile = file("test.txt");
foreach ($InputFile as $line){
preg_match('~(1-Column[^;]*;?)?(2-Column[^;]*)?;?(3-Column[^;]*)?;?(4-Column[^;]*)?;?(5-Column[^;]*)?;?(6-Column[^;]*)?;?(7-Column[^;]*)?;?~',$line,$pieces);
$pieces = array_pad($pieces,8,'');
echo "<pre>";print_r($pieces);echo "</pre>";
}
output:
Array
(
[0] => 1-Column=host1.colo.sub;2-Column=Fri Aug 13;3-Column=db9.nfl.colo2.;4-Column=00:00:03;5-Column=01:55:02;6-Column=87.24 MB;7-Column=Success;
[1] => 1-Column=host1.colo.sub;
[2] => 2-Column=Fri Aug 13
[3] => 3-Column=db9.nfl.colo2.
[4] => 4-Column=00:00:03
[5] => 5-Column=01:55:02
[6] => 6-Column=87.24 MB
[7] => 7-Column=Success
)
Array
(
[0] => 1-Column=host1.colo.sub;2-Column=Fri Aug 13;3-Column=pdb2.colo2.;4-Column=04:00:02;
[1] => 1-Column=host1.colo.sub;
[2] => 2-Column=Fri Aug 13
[3] => 3-Column=pdb2.colo2.
[4] => 4-Column=04:00:02
[5] =>
[6] =>
[7] =>
)
Array
(
[0] => 1-Column=host1.colo.sub;2-Column=Fri Aug 13;3-Column=gl3_lvm;5-Column=04:48:06;6-Column=54.64 MB;7-Column=Success;
[1] => 1-Column=host1.colo.sub;
[2] => 2-Column=Fri Aug 13
[3] => 3-Column=gl3_lvm
[4] =>
[5] => 5-Column=04:48:06
[6] => 6-Column=54.64 MB
[7] => 7-Column=Success
)

If your input data is so irregular you would either need to parse it with a bit more code, not just a simple explode, or prepare it so that it works as expected with explode.
In the second case, you could use strpos to find all ";" characters in the string and check if the number after them is in order. If one (or more) number was skipped you should compensate by inserting another ";". This way explode will create an empty array element and all your resulting arrays should be aligned.

While it's not exactly clear what you're trying to accomplish, hopefully this code might help you figure out what's going on.
Note that here, I've added another loop inside the main foreach, to iterate over each name/value pair in the line:
<?php
$InputFile = file("test.txt");
$lineCnt = 0;
foreach ($InputFile as $line){
$lineCnt++;
echo "Processing line #" . $lineCnt. "\n";
$pieces = explode(";", $line);
foreach($pieces as $pair){
$pair = explode('=',$pair);
if (!empty($pair[1])){
print "\t".$pair[0] .' = ' . $pair[1] . "\n";
}
}
}
The script will produce nice-looking output if run from the command-line. If you're running it in the browser, you might want to change the \n's to , and the \t's to or something.

See if this helps...
$splits = explode(';',$_POST['data']);
foreach($splits as $id => $item) {
preg_match('/(.*?)=(.*)/',$item, $matches);
$parts[$matches[1]][] = $matches[2];
}
print_r($parts);
This will give you an array with keys as 1-Column, 2-Column as so on which will contain an array of related value. You can print this array in whatever way you want.
Here is the output:
[1-Column] => Array
(
[0] => host1.colo.sub
[1] => host1.colo.sub
[2] => host1.colo.sub
)
[2-Column] => Array
(
[0] => Fri Aug 13
[1] => Fri Aug 13
[2] => Fri Aug 13
)
[3-Column] => Array
(
[0] => db9.nfl.colo2.
[1] => pdb2.colo2.
[2] => gl3_lvm
)
[4-Column] => Array
(
[0] => 00:00:03
[1] => 04:00:02
)
[5-Column] => Array
(
[0] => 01:55:02
[1] => 04:48:06
)
[6-Column] => Array
(
[0] => 87.24 MB
[1] => 54.64 MB
)
[7-Column] => Array
(
[0] => Success
[1] => Success
)

Related

Assign key number to php array objects

My code
$str = array(fgets($da, 1024));
print_r($str);
I'm trying to create an array in php from a dynamic output , but i noticed the keys in all object are [0], i need to assign a diferent key number to each object, how can i do that ?
Looks weird to me that all keys are 0, im trying to figure but nothing helps me.
Result :
Array
(
[0] =>
)
Array
(
[0] => 200
)
Array
(
[0] => 819105 rs fs
)
Array
(
[0] => 300 tert
)
Array
(
[0] => THO
)
Array
(
[0] => 91362
)
Array
(
[0] =>
)
Array
(
[0] => 06-20-21 6:56 PM
)
Array
(
[0] =>
)
Array
(
[0] =>
Array
(
[0] => 3 Cat 20 4.82 0.0 7.4 30
)
Array
(
[0] => 4 Dogs 19 26.2 0.8 7.1 62
)
Array
(
[0] =>
)
Thanks
If the input is reliable, you can split on whitespace for example:
$str = fgets($da, 1024);
$a = explode(" ", $str);
print_r($a);
array_merge with the spread (...) operator would work.
$str = array(fgets($da, 1024));
$str = array_merge(...$str);
All of the keys appear to be zero because you are wrapping each line from the file in its own array, so each array has one element at index zero.
If you define a buffer outside of your read loop, and add each line to it, each line will have its own index.
$da = fopen('test.txt', 'r');
// Define a buffer for the output
$data = [];
while (($str = fgets($da)) !== false)
{
// Add our line to the buffer
$data[] = $str;
}
fclose($da);
print_r($data);
output:
Array
(
[0] => 200
[1] => 819105 rs fs
[2] => 300 tert
[3] => THO
[4] => 91362
[5] => 06-20-21 6:56 PM
[6] => 3 Cat 20 4.82 0.0 7.4 30
[7] => 4 Dogs 19 26.2 0.8 7.1 62
)
But it looks like you may have some sort of header information in the first 6 lines of the file, maybe info from an HTTP request? Then lines that are somehow delimited, maybe by tab, but then the text got munged somewhere on the way into the SO post?
You can use a combination of fgets and fgetcsv to pull the data from the file and organize it into associative arrays.
Input:
200
819105 rs fs
300 tert
THO
91362
06-20-21 6:56 PM
3 Cat 20 4.82 0.0 7.4 30
4 Dogs 19 26.2 0.8 7.1 62
5 Wombat 20 4.20 0.0 6.9 30
6 Hedgehogs 19 26.2 0.8 7.1 62
$da = fopen('test.txt', 'r');
// Define a buffer for the output
$data = [];
// Define the fields in the header, each header line needs an entry
$headerDef = [
'status',
'transfer_stats',
'what_is_this',
'something_else',
'content_length',
'timestamp'
];
// Define the columns in the data rows, each column needs an entry
$columnDef = [
'id',
'type',
'count',
'average_weight',
'tax',
'food_weight_percent_per_day',
'fluffiness'
];
// Define an array to hold the header contents
$headerData = [];
// For each line in the header definition, extract a line from the file
while (!empty($headerDef) && $str = fgets($da, 1024))
{
$currValue = trim($str);
// Pull the next field from the front of the array
$currHeaderField = array_shift($headerDef);
// Set the entry in the header data array
$headerData[$currHeaderField] = $currValue;
}
while ($row = fgetcsv($da, 1024, "\t"))
{
// Create a new associative array by combining the column names and the row data
$data[] = array_combine($columnDef, $row);
}
fclose($da);
print_r($headerData);
print_r($data);
output:
Array
(
[status] => 200
[transfer_stats] => 819105 rs fs
[what_is_this] => 300 tert
[something_else] => THO
[content_length] => 91362
[timestamp] => 06-20-21 6:56 PM
)
Array
(
[0] => Array
(
[id] => 3
[type] => Cat
[count] => 20
[average_weight] => 4.82
[tax] => 0.0
[food_weight_percent_per_day] => 7.4
[fluffiness] => 30
)
[1] => Array
(
[id] => 4
[type] => Dogs
[count] => 19
[average_weight] => 26.2
[tax] => 0.8
[food_weight_percent_per_day] => 7.1
[fluffiness] => 62
)
[2] => Array
(
[id] => 5
[type] => Wombat
[count] => 20
[average_weight] => 4.20
[tax] => 0.0
[food_weight_percent_per_day] => 6.9
[fluffiness] => 30
)
[3] => Array
(
[id] => 6
[type] => Hedgehogs
[count] => 19
[average_weight] => 26.2
[tax] => 0.8
[food_weight_percent_per_day] => 7.1
[fluffiness] => 62
)
)
Of course the field names are just made up, I have no idea what your actual data is. And I'm assuming that the data rows are delimited with tabs, that may not be the case. But you should be able to use this as a starting point.
PS. It could be that the HTTP data at the top of the file is included by mistake, perhaps from a curl request? You could change that with the CURLOPT_HEADER option and curl_setopt

How to extract certain words from a php string?

I have a long string like this I1:1;I2:2;I8:2;NA1:5;IA1:[1,2,3,4,5];S1:asadada;SA1:[1,2,3,4,5];SA1:[1,2,3,4,5];. Now I just want to get certain words like 'I1','I2','I8','NA1' and so on i.e. words between ':'&';' only ,and store them in array. How to do that efficiently?
I have already tried using preg_split() and it works but giving me wrong output. As shown below.
// $a is the string I want to extract words from
$str = preg_split("/[;:]/", $a);
print_r($str);
The output I am getting is this
Array
(
[0] => I8
[1] => 2
[2] => I1
[3] => 1
[4] => I2
[5] => 2
[6] => I3
[7] => 2
[8] => I4
[9] => 4
[10] =>
)
Array
(
[0] => NA1
[1] => 5
[2] =>
)
Array
(
[0] => IA1
[1] => [1,2,3,4,5]
[2] =>
)
Array
(
[0] => S1
[1] => asadada
[2] =>
)
Array
(
[0] => SA1
[1] => [1,2,3,4,5]
[2] =>
)
But I am expecting 'I8','I1','I2','I3','I4' also in seperated array with position [0]. Any help on how to do this.
You could try something like.
<?php
$str = 'I1:1;I2:2;I8:2;NA1:5;IA1:[1,2,3,4,5];S1:asadada;SA1:[1,2,3,4,5];SA1:[1,2,3,4,5];';
preg_match_all('/(?:^|[;:])(\w+)/', $str, $result);
print_r($result[1]); // Matches are here in $result[1]
You can perform a greedy match to match the items between ; and : using preg_match_all()
<?php
$str = 'I1:1;I2:2;I8:2;NA1:5;IA1:[1,2,3,4,5];S1:asadada;SA1:[1,2,3,4,5];SA1:[1,2,3,4,5];';
preg_match_all('/;(.+?)\:/',$str,$matches);
print_r($matches[1]);
Live Demo: https://3v4l.org/eBsod
One possible approach is using a combination of explode() and implode(). The result is returned as a string, but you can easily put it into an array for example.
<?php
$input = "I1:1;I2:2;I8:2;NA1:5;IA1:[1,2,3,4,5];S1:asadada;SA1:[1,2,3,4,5];SA1:[1,2,3,4,5];.";
$output = array();
$array = explode(";", $input);
foreach($array as $item) {
$output[] = explode(":", $item)[0];
}
echo implode(",", $output);
?>
Output:
I1,I2,I8,NA1,IA1,S1,SA1,SA1,.

How to merge subarray values and generate a 1-dimensional array of unique values?

How to get final unique array result from multiple array?
I have an array like this:
Array
(
[0] => Array
(
[0] => 8
[1] => 9
[2] => 7
)
[1] => Array
(
[0] => 7
[1] => 8
[2] => 9
[3] => 33
[4] => 21
)
[2] => Array
(
[0] => 11
[1] => 12
[2] => 33
[3] => 21
[4] => 9
[5] => 31
)
)
Expected result:
Array(
[0] => 7
[1] => 8
[2] => 9
[3] => 33
[4] => 21
[5] => 11
[6] => 12
[7] => 31
)
How to do that using php?
In your desired output indexes are same, you never achieve that. because same indexes are over-written by most recent values.
You can get like below:-
$final_array = array_unique(call_user_func_array('array_merge', $array)); //convert multi-dimensional array to single dimensional and remove duplicates
asort($final_array); // sort by value. this is optional
$final_array = array_values($final_array); // re-index final array and this is optional too
echo "<pre/>";print_r($final_array); // print final array
Output:- https://eval.in/752750
This takes three core PHP functions, sort, array_merg, and array_unique:
sort - sorts an array sent in by reference, meaning rather than returning a variable, it changes the order of the array itself.
array_merg - when combines with call_user_func_array will dynamically combine all the arrays together, however many there are.
array_unique - make sure there is only one of each element.
<?php
$arr = [ [8,9,7], [7,8,9,33,21], [11,12,33,21,9,31] ];
$merged = array_unique(call_user_func_array('array_merge', $arr));
sort($merged);
print_r($merged);
?>
Output:
Array
(
[0] => 7
[1] => 8
[2] => 9
[3] => 11
[4] => 12
[5] => 21
[6] => 31
[7] => 33
)
And here's it inside of eval.in:
https://eval.in/752793
This the way
<?php
$arr = [ [8,9,7], [7,8,9,33,21], [11,12,33,21,9,31] ];
$final = array();
foreach($arr as $child){
foreach($child as $value){
$final[] = $value;
}
}
$final = array_unique($final);
print_r($final);
?>
Demo : https://eval.in/752766
Output :
Array
(
[0] => 8
[1] => 9
[2] => 7
[6] => 33
[7] => 21
[8] => 11
[9] => 12
[13] => 31
)
Method #1: foreach loops with isset() that sort values by their first occurrence (Demo)(*this method seems to be the fastest of all)
$array=[[8,9,7],[7,8,9,33,21],[11,12,33,21,9,31]];
foreach($array as $sub){
foreach($sub as $v){
if(!isset($result[$v])){ // only add first occurence of a value
$result[$v]=$v;
}
}
}
var_export(array_values($result)); // re-index and print to screen
// condensed output: array(8,9,7,33,21,11,12,31)
Method #2: assign temporary keys which force value-overwriting to ensure no duplicates (Demo)
$array=[[8,9,7],[7,8,9,33,21],[11,12,33,21,9,31]];
foreach($array as $sub){
foreach($sub as $v){
$result[$v]=$v; // force overwrite because duplicate keys cannot occur
}
}
sort($result); // sort and re-index
var_export($result); // print to screen
// condensed output: array(7,8,9,11,12,21,31,33)
Method #3: array_merge() with splat operator and array_unique() (Demo)
$array=[[8,9,7],[7,8,9,33,21],[11,12,33,21,9,31]];
$unique=array_unique(array_merge(...$array)); // merge all subarrays
sort($unique); // sort and re-index
var_export($unique); // print to screen
// condensed output: array(7,8,9,11,12,21,31,33)
Method #4: unorthodox json_encode() & preg_match_all() (Demo) (Pattern Demo)
$array=[[8,9,7],[7,8,9,33,21],[11,12,33,21,9,31]];
$unique=preg_match_all('~\b(\d+)\b(?!.*\b\1\b)~',json_encode($array),$out)?$out[0]:[];
sort($unique); // sort and re-index
var_export($unique); // print to screen
// condensed output: array(7,8,9,11,12,21,31,33)

regexp - match multiple variations of datestamp

I need to match multiple variations of a datestamp
$test = array(
'01-05-2011',
'01-05-11',
'01.12.2012',
'30042016'
);
$date_day_pattern = '01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31';
$date_year_pattern = '(?:20)?10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30';
$date_pattern = "(?<!\d)($date_day_pattern)[^\d\n]?($date_day_pattern)[^\d\n]?($date_year_pattern)(?!\d)";
foreach($test as $input){
preg_match("/$date_pattern/", $input, $matches);
print_r($matches);
}
http://www.tehplayground.com/#R1sjJxFho
This shortened regex should work for your examples:
$test = array(
'01-05-2011',
'01-05-11',
'01.12.2012',
'30042016'
);
$date_pattern =
'/\b(0[1-9]|[12][0-9]|3[01])([.-]?)(0[1-9]|1[0-2])\2((?:20)?(?:[12][0-9]|30))\b/';
foreach($test as $input){
echo $input."\n";
preg_match($date_pattern, $input, $matches); print_r($matches);
}
Though you should consider using date parsing functions such as strtotime for proper date validations and parsing.
Output:
01-05-2011
Array
(
[0] => 01-05-2011
[1] => 01
[2] => 05
[3] => 2011
)
01-05-11
Array
(
[0] => 01-05-11
[1] => 01
[2] => 05
[3] => 11
)
01.12.2012
Array
(
[0] => 01.12.2012
[1] => 01
[2] => 12
[3] => 2012
)
30042016
Array
(
[0] => 30042016
[1] => 30
[2] => 04
[3] => 2016
)
I have written a pattern that should work. It looks slightly different than yours, but matches every case you have described there and fails in any other case.
'(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[01])-(?:20)?(?:[1-2][0-9]|30))|(?:(?:0[1-9]|[1-2][0-9]|3[[01]])(\.?)(?:0[1-9]|1[0-2])(\1)20(?:[1-2][0-9]|30))'
Explanation:
I have combined case1&2 and case3&4 and have written a pattern for each of those and merged them together with a logical or. The code is pretty straightforward, the only noteworthy thing is the backreference in the second part that is used to allow two dots/no dots and not a mixture.

Summary, reorganizing and "flatten" the entire multi-dimensional array

Currently I have an array like :
Array(
[0] => Array([range]=>1-10 [count]=>3 [type]=>A)
[1] => Array([range]=>11-20 [count]=>6 [type]=>A)
[2] => Array([range]=>21-30 [count]=>5 [type]=>A)
[3] => Array([range]=>1-10 [count]=>5 [type]=>B)
[4] => Array([range]=>11-20 [count]=>3 [type]=>B)
[5] => Array([range]=>21-30 [count]=>8 [type]=>B)
[6] => Array([range]=>1-10 [count]=>4 [type]=>C)
[7] => Array([range]=>11-20 [count]=>3 [type]=>C)
[8] => Array([range]=>21-30 [count]=>6 [type]=>C)
[9] => Array([range]=>1-10 [count]=>3 [type]=>D)
[10] => Array([range]=>11-20 [count]=>7 [type]=>D)
And then I am trying to regroup/remake the array depends on their type and the expected output would be like :
Array(
[0] => Array([type]=>A [1-10]=>3 [11-20]=>6 [21-30]=>5)
[1] => Array([type]=>B [1-10]=>5 [11-20]=>3 [21-30]=>8)
[2] => Array([type]=>C [1-10]=>4 [11-20]=>3 [21-30]=>6)
[3] => Array([type]=>D [1-10]=>3 [11-20]=>7)
)
I have tried array_column but isn't what exactly I want...
Example Here.
Thanks in advance.
This should work for you:
Here I simply loop through the entire array and then check with isset() if the result array already has an innerArray with the same type (e.g $result["A"]), if not I add the type as value to the inner array (.e.g. $result["A"]["type"] = "A";).
After this check I simply add the range and count to each type (e.g. $result["A"]["1-10"] = 3;)
At the end I simply reindex the entire $result array with array_values().
<?php
foreach($arr as $k => $v) {
if(!isset($result[$v["type"]]))
$result[$v["type"]]["type"] = $v["type"];
$result[$v["type"]][$v["range"]] = $v["count"];
}
$result = array_values($result);
print_r($result);
?>
output:
Array
(
[0] => Array
(
[type] => A
[1-10] => 3
[11-20] => 6
[21-30] => 5
)
//...
)

Categories