Explode txt file into multidimensional array - php

I have a .txt file that looks like the one below:
Test = 10849831 = August 6, 2013:
56cake = 0 = August 6, 2013:
Wwe = 812986192 = August 6, 2013:
I want to explode the file above to make an array that looks like the one below:
Array
(
[Test] => Array
(
[0] => 10849831
[1] => August 6, 2013
)
[56cake] => Array
(
[0] => 0
[1] => August 6, 2013
)
[Wwe] => Array
(
[0] => 812986192
[1] => August 6, 2013
)
)
How can I accomplish this? I've already tried using something like explode(":", $data) but I don't know how to use it to do what I want above. I'm fairly new with PHP.

Just a little bit of array iteration does the trick with: explode, array_map, trim, isset and foreach.
PHP Example
$txt = <<<DOC
Test = 10849831 = August 6, 2013:
56cake = 0 = August 6, 2013:
Wwe = 812986192 = August 6, 2013:
DOC;
$Output = array();
$Lines = explode(":", $txt);
foreach($Lines as $line) {
$Rows = array_map('trim', explode(" = ", $line));
if(!isset($Rows[0], $Rows[1], $Rows[2])) continue;
$Output[$Rows[0]] = array($Rows[1], $Rows[2]);
}
print_r($Output);
PHP Code Output
Array
(
[Test] => Array
(
[0] => 10849831
[1] => August 6, 2013
)
[56cake] => Array
(
[0] => 0
[1] => August 6, 2013
)
[Wwe] => Array
(
[0] => 812986192
[1] => August 6, 2013
)
)
The Code Explained
Break up the lines with explode(":", $txt)
Loop through each line and break up each section by = again using explode
Use array_map to cycle each value and remove whitespace
Check to ensure we have 3 values with isset, if not, then skip the iteration
Push our collected values into the output array

Something like this?
<?php
// Sample text data
$text = 'Test = 10849831 = August 6, 2013:
Test = 10849831 = August 6, 2013:
56cake = 0 = August 6, 2013:
Wwe = 812986192 = August 6, 2013:';
$text = explode( PHP_EOL, $text ); // split by lines using linebreaks
// $text = explode( ":", $text ); // you can also split by lines with ':'
$arr = array(); // Our array which holding the output
// print_r( $text );
foreach( $text as $line ) { // loop through lines
$line = array_map( "trim", explode( "=", $line ) ); // split by '=' sign and do 'trim'
// print_r( $line );
if ( count( $line ) === 3 ) {
$key = strtolower( $line[0] ); // make the key lowercase (case insensitive)
$val1 = $line[1];
// process the date and remove day from date
$val2 = trim( $line[2], ":" ); // remove ':' from the end of date
$val2 = array_map( "trim", explode( " ", $val2 ) ); // split by space sign and do a 'trim'
$val2 = $val2[0]." ".$val2[2]; // join year and month parts
if ( isset( $arr[$key] ) ) { // check if the key already exists
// key exists, push new values
array_push( $arr[$key], $val1, $val2 );
continue; // key exists so continue the loop
}
// key doesn't exists in array so add the values
$arr[$key] = array( $val1, $val2 );
}
}
// there is an altwernate way to remove duplicate values using 'array_unique'
// uncomment below code if you dont want duplicate values
/*if ( !empty( $arr ) ) {
$arr = array_map( "array_unique", $arr ); // remove duplicate values from array using 'array_unique'
}*/
print_r( $arr );
?>
Here is the list of functions which i used in my code and link to those functions documentation
explode
array_map
trim
count
strtolower
isset
array_push
array_unique

Try to re-use this code:
<?php
echo '<pre>';
$result = array();
$string = 'Test = 10849831 = August 6, 2013';
$temp1 = explode("=", $string, 2);
print_r($temp1);
/*
Array
(
[0] => Test
[1] => 10849831 = August 6, 2013
)
*/
$key = $temp1[0];
$result[$key] = explode("=", $temp1[1]);
print_r($result);
/*
Array
(
[Test ] => Array
(
[0] => 10849831
[1] => August 6, 2013
)
)
*/
?>

$chunks = explode(':', $text);
$out = array();
foreach ($chunks as $key => $value){
$parts = explode('=', $value);
if (count($parts) == 3){
$out[trim($parts[0])] = array(trim($parts[1]), trim($parts[2]));
}
}
print_r($out);

You have use explode like this:
<?php
//
//Test = 10849831 = August 6, 2013:
//56cake = 0 = August 6, 2013:
//Wwe = 812986192 = August 6, 2013:
function read_data_file( $file ) {
$file_open = fopen( $file , 'r' );
$file_data = fread( $file_open , filesize( $file ) );
fclose( $file_open );
return $file_data;
}
$result_read = read_data_file('/home/josecarlos/Desktop/test.txt');
$result_explode = explode("\n", $result_read );
$final_result = array();
foreach ($result_explode as $key => $cursor){
$explode = explode("=", $cursor );
if (isset($explode[0]) && $explode[0] != ''){
$final_result[trim($explode[0])] =array (trim($explode[1]),trim($explode[2])) ;
}
}
var_dump($final_result);
The result is:
array(3) {
'Test' =>
array(2) {
[0] =>
string(8) "10849831"
[1] =>
string(15) "August 6, 2013:"
}
'56cake' =>
array(2) {
[0] =>
string(1) "0"
[1] =>
string(15) "August 6, 2013:"
}
'Wwe' =>
array(2) {
[0] =>
string(9) "812986192"
[1] =>
string(15) "August 6, 2013:"
}
}

Related

PHP reading data input from a text file

I have a text file which I must read, and use the data from.
3
sam 99912222
tom 11122222
harry 12299933
sam
edward
harry
How can I create an array of these strings in the following form?
array(
"name" => "number"
...
)
I tried this:
$handle = fopen("file.txt", "r");
fscanf($handle, "%d %d", $name, $number);
What then? No matter what I try, it only works for the first line.
sam 99912222
Added codes to have both types of output - ignoring and including the lines that don't have name-value pairs. Check them out below
This code goes through each line and gets only the ones that have both name and value (something[space]something)):
//$lines = ... each line of the file in an array
$vals = array();
foreach($lines as $v){
$tmp = explode(' ', $v);
if(count($tmp) > 1){
$vals[trim($tmp[0])] = trim($tmp[1]); // trim to prevent garbage
}
}
print_r($vals);
It will output this:
Array
(
[sam] => 99912222
[tom] => 11122222
[harry] => 12299933
)
See the code in action here.
If you need the values even if they didn't come in pairs, do it like this:
//$lines = ... each line of the file
$vals = array();
foreach($lines as $v){
$tmp = explode(' ', $v);
$name = '';
$number = '';
$tmp[0] = trim($tmp[0]);
if(count($tmp) > 1){
$name = $tmp[0];
$number = trim($tmp[1]);
}else{
if(is_numeric($tmp[0])){
$number = $tmp[0];
}else{
$name = $tmp[0];
}
}
$vals[] = array(
'name' => $name,
'number' => $number
);
}
print_r($vals);
And the output:
Array
(
[0] => Array
(
[name] =>
[number] => 3
)
[1] => Array
(
[name] => sam
[number] => 99912222
)
[2] => Array
(
[name] => tom
[number] => 11122222
)
[3] => Array
(
[name] => harry
[number] => 12299933
)
[4] => Array
(
[name] => sam
[number] =>
)
[5] => Array
(
[name] => edward
[number] =>
)
[6] => Array
(
[name] => harry
[number] =>
)
See the code in action here.
Data in file are inconsistent, best of is to use regex to identify what data you've got from each line.
$lines = file('file.txt'); // this will open file and split them into lines
$items = array();
foreach($lines as $line){
$name = null;
$number = null;
$nameFound = preg_match("|([A-Za-z]+)|", $line, $matches);
if($nameFound){
$name = $matches[0];
}
$numberFound = preg_match("|([0-9]+)|", $line, $matches);
if($numberFound){
$number = $matches[0];
}
$items[] = array('name' => $name, 'number' => $number);
}
Then in items you should find parsed data from file.
To make it just extract full format data just change lines with regex into one line like this:
$lines = file('file.txt'); // this will open file and split them into lines
$items = array();
foreach($lines as $line){
$userFound = preg_match("/([A-Za-z]+) ([0-9]+)/", $line, $matches);
if($userFound){
$items[$matches[1]] = $matches[2];
}
}
With the Algorithm below, you can simply parse each individual line of the Text-File Contents into an array with the 1st Word or Digit(s) on each line as the Key and the 2nd Word as the Value. When the 2nd word or group of words do not exist, a NULL is assigned to that Key. For re-usability, this algorithm has been encapsulated into a Function. Here you go:
<?php
function parseTxtFile($txtFile){
$arrTxtContent = [];
if(!file_exists($txtFile)){ return null;}
$strFWriteTxtData = file_get_contents($txtFile);
if(empty($strFWriteTxtData)){return null;}
$arrFWriteInfo = explode("\n", $strFWriteTxtData);
foreach($arrFWriteInfo as $iKey=>$lineData){
$arrWriteData = explode(", ", $lineData);
foreach($arrWriteData as $intKey=>$strKeyInfo){
preg_match("#(^[a-z0-9_A-Z]*)(\s)(.*$)#i", $strKeyInfo, $matches);
preg_match("#(^[a-z0-9_A-Z]*)(\s*)?$#i", $strKeyInfo, $matches2);
if($matches) {
list(, $key, $null, $val) = $matches;
if (!array_key_exists($key, $arrTxtContent)) {
$arrTxtContent[$key] = $val;
}else{
$iKey = $intKey + 1;
$key = $key . "_{$iKey}";
$arrTxtContent[$key] = $val;
}
}else if($matches2) {
list(, $key, $null) = $matches2;
if (!array_key_exists($key, $arrTxtContent)) {
$arrTxtContent[$key] = null;
}else{
$key = preg_match("#_\d+#", $key, $match)? $key . $match[0] : "{$key}_1";
$arrTxtContent[$key] = null;
}
}
}
}
return $arrTxtContent;
}
var_dump(parseTxtFile(__DIR__ . "/data.txt"));
Just call the function parseTxtFile($txtFile) passing it the path to your text File and it will return an Array that looks something like below:
array (size=7)
3 => null
'sam' => string '99912222' (length=8)
'tom' => string '11122222' (length=8)
'harry' => string '12299933' (length=8)
'sam_1' => null
'edward' => null
'harry_1' => null
Hope this could help a bit....
Cheers & Good-Luck ;-)

Get specific content from a string

I need to get numbers as an array from a given string.
Example string:
$t = '1-P,2-T,3-P,4-R,5-C,6-T,';
Expected output:
if I search -T the output needs to be like this:
array(
[0] => 2,
[1] => 6
)
if it's -P:
array(
[0] => 1,
[1] => 3
)
I tried var_export(explode("-T,",$t)); but it didn't work as expected.
Can any one give me a suggestion to get this?
The below matches the full integer number which preceeds the search term -P.
Let's keep it concise:
$matches = array();
if (preg_match_all('/([0-9]+)\-P/', $t, $matches) >= 1) {
var_dump($matches[1]);
}
Search for '/([0-9]+)\-P/, '/([0-9]+)\-C/, '/([0-9]+)\-T/ an so on.
A more dynamic way to look for different search terms/filters:
$filter = '-T';
$pattern = sprintf('/([0-9]+)%s/', preg_quote($filter));
See preg_match_all and preg_quote functions.
Try this:
$t = '211111111131-P,2-T,3654554-P,4-R,5-C,6-T,';
$find = "-P"; // Search element
$found = []; // Result array
$array = explode(",", $t); // Breaking up into array
foreach($array as $arr) {
if (strpos($arr, $find)) { // Checking if search element is found in $arr
$found[] = explode('-',$arr)[0]; // Extracting the number prefix e.g 1 for 1-P
}
}
Output:
Array
(
[0] => 1
[1] => 3
)
Use it as
$t = '1-P,2-T,3-P,4-R,5-C,6-T,';
$data = explode(",", $t);
print_r($data);
$row=array();
for ($i = 0; $i <= count($data); $i++) {
if (!empty($data[$i])) {
if (strpos($data[$i], '-T') !== false) {// pass find value here
$final = explode("-", $data[$i]);
$row[]=$final[0];
}
}
}
print_r($row);
Output
Array
(
[0] => 2
[1] => 6
)
DEMO
$t = '1-P,2-T,3-P,4-R,5-C,6-T,';
$temp = [];
// if the last comma is not typo the 3rd argument `-1` omit empty item
$array = explode(",", $t, -1);
foreach($array as $arr) {
list($v, $k) = explode('-', $arr);
$temp[$k][] = $v;
}
print_r($temp['T']);
demo
Lots of good answers here already, but none take the approach of first putting the data into a better structure.
The code below converts the data to an associative array mapping letters to arrays of numbers, so that you can then do repeated lookups by whichever letter you want:
$t = '1-P,2-T,3-P,4-R,5-C,6-T,';
$a = array_filter(explode(',', $t));
$map = [];
foreach($a as $item) {
$exploded = explode('-', $item);
$number = $exploded[0];
$letter = $exploded[1];
if (!array_key_exists($letter, $map)) {
$map[$letter] = [];
}
$map[$letter][] = $number;
}
print_r($map);
// Array
// (
// [P] => Array
// (
// [0] => 1
// [1] => 3
// )
//
// [T] => Array
// (
// [0] => 2
// [1] => 6
// )
//
// [R] => Array
// (
// [0] => 4
// )
//
// [C] => Array
// (
// [0] => 5
// )
//
// )
print_r($map['T']);
// Array
// (
// [0] => 2
// [1] => 6
// )
print_r($map['P']);
// Array
// (
// [0] => 1
// [1] => 3
// )

Converting this (array string ) from a file into php array

I have an export from a legacy system which i want to import into an RDBMS solution.
The export file has data as the example below
%a = (
'1' => 'test',
'3' => 'test2',
'44' => 'this is another test()
);
%b = (
'1' => 'super man'
);
%c = (
'username' => 'testing'
);
I wish to get these files into associative php array so that i can iterate into the database table, check if the values exist and save it if it does not exist.
I am stuck with the parsing of the file part.
so far i have been able to reach here
$string = file_get_contents($path);
$params = explode("%", $string); // to separate the main chunks
foreach ($params as $keyvalue) {
if ($keyvalue!='') { //as the file starts with % to truncate the first blank result
$trimmed=substr(trim($keyvalue, ' '), 3, strlen($keyvalue) - 4); // remove this part from the result 'a='
$finalArray = explode(";", $trimmed); // remove the semi column
$array = $finalArray[0];
print_r($array );
echo '<br/>';
echo '<br/>';
echo '<br/>';
echo '<br/>';
}
with the above i do get this output
( "1" => "test", "3" => "test2" ,'44' => 'this is another test())
( '1' => 'super man' )
('username' => 'testing' )
displayed on different lines, i tried json_decode (...,true), unserialise ect to convert this output into array so that i can loop with no success.
Any help will be most welcomed.
try this
$array[] = $finalArray[0];
Because you creating new array everytime. You need to append to the existing array so as to get the desired output.
And my edited code is below
$params = explode("%", $string);
$i = 0;
foreach ($params as $keyvalue) {
if ($keyvalue!='') {
$trimmed=substr(trim($keyvalue, ' '), 3, strlen($keyvalue) - 4);
$finalArray = explode(";", $trimmed);
$array = $finalArray[0];
$newArray = explode(',',substr($array, 1, -1));
foreach($newArray as $arravalue) {
$newArray1 = explode('=>',substr($arravalue, 1, -1));
$finalResultArray[$i][trim(str_replace("'","",$newArray1[0]))] = '"'.trim(str_replace("'","",$newArray1[1])).'"';
}
$i++;
}
}
It gives an output array $finalResultArray with the below format.
Array
(
[0] => Array
(
[1] => "test"
[3] => "test2"
[44] => "this is another test("
)
[1] => Array
(
[1] => "super man"
)
[2] => Array
(
[username] => "testing"
)
)
I made a little tweek with string replace to do the trick, by converting it to a json format replacing the ( by { the => by : and ) by }
it seem to work fine but if there is a neater solution I would like to welcome it.
$string = file_get_contents($path);
$params = explode("%", $string);
foreach ($params as $keyvalue) {
if ($keyvalue!='') {
$trimmed=substr(trim($keyvalue, ' '), 3, strlen($keyvalue) - 4);
$finalArray = explode(";", $trimmed);
$array = $finalArray[0];
print_r($array); // display 1
$string2 = str_replace('(', '{', $array);
$string3 = str_replace(')', '}', $string2);
$string4 = str_replace('=>', ':', $string3);
$ar = json_decode($string4);
echo ('<pre>');
//echo $first; // value
print_r( $ar);
echo('</pre>'); //display 2
die('wa');
echo '<br/>';
echo '<br/>';
echo '<br/>';
echo '<br/>';
}
}
//display 1
( "1" => "test1", "2" => "test2", "3" => "test4")
display 2
stdClass Object
(
[1] => test1
[2] => test2
[3] => test4
)

How to extract useful information from a string with PHP

I'm using a string that is composed the following way:
0003customer-23892644362977289 28 23892644362977293 29 23892644362977294 30
First four characters: The number of registries to be processed.
String "customer-": Defines the table to be used
The next part of the chain is defined as a key => value for a string (uuid_short => remote id)
I need to separate each part of the chain so it can be processed locally.
I tried using substrings, explode and the following loop:
$array = explode(" ", $string);
for($i = 0, $b = 0; $b < $num_of_registries; $i = $i + 2, $b++)
{
$local = $array[$i];
$remote = $array[$i+1];
// store values in array
$inserted = array();
$inserted['local'] = $local;
$inserted['remote'] = $remote;
$array_inserted[] = $inserted;
}
foreach ($array_inserted as $key => $value)
{
echo $value["local"].' => '.$value["remote"].' <p>';
}
But the loop only works with single character value pairs.
Voila.
if (preg_match("#^([0-9]+)(.*?)-(.*)#", $string, $out)) {
echo "number: ".$out[1]."\n";
echo "table: ".$out[2]."\n";
if (preg_match_all("#([0-9]+) ([0-9]+)#", $out[3], $res, PREG_SET_ORDER))
foreach ($res as $r) echo "$r[1] => $r[2]\n";
}
Result
number: 0003
table: customer
23892644362977289 => 28
23892644362977293 => 29
23892644362977294 => 30
Due to the lack of a representation, this is merely speculative.
This is what I came up with:
<?
$string='0003customer-23892644362977289 28 23892644362977293 29 23892644362977294 30';
$array = explode('-', $string);
$header = current( $array );
$times = (int)$header;
$data = array();
$data[$key = substr($header, 4)] = explode(' ', $array[1]);
print_r($data);
Should output:
Array
(
[customer] => Array
(
[0] => 23892644362977289
[1] => 28
[2] => 23892644362977293
[3] => 29
[4] => 23892644362977294
[5] => 30
)
)
If you want key=>value, you may want this:
$string='0003customer-23892644362977289 28 23892644362977293 29 23892644362977294 30';
$array = explode('-', $string);
$header = current( $array );
$times = (int)$header;
$key = substr($header, 4);
$data = array("$key"=>array());
$content = explode(' ', $array[1]);
for($i=0;$i < $times * 2;)
{
$data[$key][$content[$i++]]=$content[$i++];
}
print_r($data);
Which prints:
Array
(
[customer] => Array
(
[23892644362977289] => 28
[23892644362977293] => 29
[23892644362977294] => 30
)
)
Or this:
$string='0003customer-23892644362977289 28 23892644362977293 29 23892644362977294 30';
$array = explode('-', $string);
$header = current( $array );
$times = (int)$header;
$key = substr($header, 4);
$data = array("$key"=>array());
$content = explode(' ', $array[1]);
for($i=0;$i < $times * 2;)
{
$data[$key][$content[1+$i++]]=$content[$i++-1];
}
print_r($data);
Which prints:
Array
(
[customer] => Array
(
[28] => 23892644362977289
[29] => 23892644362977293
[30] => 23892644362977294
)
)
Edit:
Removed the $times * 2 on every explode(), in case the input comes as 0001customer-23892644362977289 28 23892644362977293 29 23892644362977294 30 (notice the 0001).
I suck at regex, so I like to write regular PHP code so I know what's going on. Here you go:
$input = "0003customer-23892644362977289 28 23892644362977293 29 23892644362977294 30";
$resistry_count = substr($input, 0, 4); // example: '0003'
$table = substr($input, 4, strpos($input, '-') - 4); // example: 'customer'
$data = substr($input, strpos($input, '-') + 1); // example: '23892644362977289 28 23892644362977293 29 23892644362977294 30'
$exploded = explode(" ", $data);
$chunked = array_chunk($exploded, 2);
$array = [];
foreach ($chunked as $row) {
$array[$row[0]] = $row[1];
}
and your result should be:
Array
(
[23892644362977289] => 28
[23892644362977293] => 29
[23892644362977294] => 30
)
This could be possible through a single regex.
(?:^(.{4})([^-]*)|\G)[\s-](\S+)\s+(\S+)
DEMO
$str = "0003customer-23892644362977289 28 23892644362977293 29 23892644362977294 30";
preg_match_all('~(?:^(.{4})([^-]*)|\G)[\s-](\S+)\s+(\S+)~', $str, $matches);
echo "Number : ".$matches[1][0]."\n";
echo "Table : ".$matches[2][0]."\n";
print_r($matches[3]);
print_r($matches[4]);

Explode a .txt file into multidimensional array

Currently I have a file that looks something like this:
Awesomedude123 = 399,408 = September 16, 2012:
Username11 = 1,914,144 = September 16, 2012:
EpicSurfer = 1,031,427 = September 16, 2012:
What I want to do is transform it into a multidimensional array with PHP so it looks something like this:
Array
(
[1] => Array
(
[0] => Awesomedude123
[1] => 399,408
[2] => September 16, 2012
)
[2] => Array
(
[0] => Username11
[1] => 1,914,144
[2] => September 16, 2012
)
[3] => Array
(
[0] => EpicSurfer
[1] => 1,031,427
[2] => September 16, 2012
)
)
I have tried using array_shift, but it didn't work out. Any help would be HIGHLY appreciated!
Here is the code:
<?php
$data = file_get_contents('File.txt'); // Get the file content
$data = str_replace(array("\n", "\r"), '', $data); // Clear newline characters
$data = explode(':', $data); // Get each record by : at end of line
unset($data[count($data) - 1]); // Clear the last empty element
$final_array = array();
foreach($data AS $row){ // Loop the exploded data
$final_array[] = explode(' = ', $row); // Explode each row by Space=Space to each row of final_array
}
print_r($final_array);
?>
You can use a regular expression to split your string:
myarray = array();
$file = fopen("myfile",'r');
while (!feof($file)) {
$line = fgets($file);
preg_match("/(\w+) = (.+) = (.+)/",$line,$matches);
myarray[] = array($matches[1],$matches[2],$matches[3]);
}

Categories