How to extract useful information from a string with PHP - 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]);

Related

How to split array in php?

I am little bit confused to get first and last value from array. And I tried to use explode()function but my logic is not working properly and very stupid logic.
My array
Array
(
[0] => 500 - 1112
[1] => 1113 - 2224
[2] => 2225 - 4446
[3] => 4446
)
I tried this way
$range = explode(',', $price_range);
$count = count($range);
if (1 == $count) {
$price_1 = $range[0];
$ranges['range1'] = explode(' - ', $price_1);
} else if (2 == $count) {
$price_1 = $range[0];
$price_2 = $range[1];
$ranges['range1'] = explode(' - ', $price_1);
$ranges['range2'] = explode(' - ', $price_2);
} else if (3 == $count) {
$price_1 = $range[0];
$price_2 = $range[1];
$price_3 = $range[2];
$ranges['range1'] = explode(' - ', $price_1);
$ranges['range2'] = explode(' - ', $price_2);
$ranges['range3'] = explode(' - ', $price_3);
} else if (4 == $count) {
$price_1 = $range[0];
$price_2 = $range[1];
$price_3 = $range[2];
$price_4 = $range[3];
$ranges['range1'] = explode(' - ', $price_1);
$ranges['range2'] = explode(' - ', $price_2);
$ranges['range3'] = explode(' - ', $price_3);
$ranges['range4'] = explode(' - ', $price_4);
}
$array = call_user_func_array('array_merge', $ranges);
sort($array);
$min = reset($array);
$max = end($array);
As per my array I want if in array getting single value in array for example
Array
(
[0] => 500 - 1112
[1] => 1113 - 2224
[2] => 2225 - 4446
[3] => 4446
)
So I want to convert this array as shown below,
Array
(
[0] => array(
[0] => 500
[1] => 1112
[2] => 1113
[3] => 2224
[4] => 2225
[5] => 4446
)
[1] => 4446
)
And get min and max from Array ( [0] => array( from this array. Is their any simple way to do.
Thanks in advance
If I correctly understand your example, you provided it with the parameter $count to 2.
So, this could be my version of your request:
The data
<?php
$data[] = '500 - 1112';
$data[] = '1113 - 2224';
$data[] = '4446';
The function
<?php
function explodeRanges(array $data, $counter, $explode = '-') {
$return = [];
// We take the correct number of rows
foreach( array_slice($data, 0, $counter) as $value ) {
$return = array_merge(
$return,
array_map('trim', explode($explode, $value))
);
// trim() function mapped on each elements to clean the data (remove spaces)
// explode all values by the separator
}
return $return;
}
The output
<?php
for( $i = 1 ; $i <= 4 ; $i++ ) {
$range = explodeRanges($data, $i);
echo 'For ', $i, ' => [', implode(', ', $range), ']; MIN = ', min($range), '; MAX = ', max($range);
echo '<hr />';
}
... and the result :)
For 1 => [500, 1112]; MIN = 500; MAX = 1112
For 2 => [500, 1112, 1113, 2224]; MIN = 500; MAX = 2224
For 3 => [500, 1112, 1113, 2224, 4446]; MIN = 500; MAX = 4446
For 4 => [500, 1112, 1113, 2224, 4446]; MIN = 500; MAX = 4446
If you need to repeat your code several times, it's because you can improve it. Here it's quick with a simple function.

php dynamic number array add missing values defined by a range

I have looked and googled many times I found a few posts that are simular but I can not find the answer Im looking for so I hope you good people can help me.
I have a function that returns a simple number array. The array number values are dynamic and will change most frequently.
e.g.
array(12,19,23)
What I would like to do is take each number value in the array, compare it to a set range and return all the lower value numbers up to and including the value number in the array.
So if I do this:
$array = range(
(11,15),
(16,21),
(22,26)
);
The Desired output would be:
array(11,12,16,17,18,19,22,23)
But instead I get back all the numbers in all the ranges.
array(11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26)
What would be a simple solution to resolve this?
Try this code
$range = array(
array(11,15),
array(16,21),
array(22,26),
);
$array = array(12,19,23);
$result = array();
foreach($range as $key=>$value)
{
//$range1 =$range[$key];
$min = $range[$key][0];
$max = $range[$key][1];
for($i = $min;$i<=$max;$i++)
{
if($i <= $array[$key])
{
array_push($result,$i);
}
}
}
echo "<pre>";print_r($result);
Iterate over each element, find the the start and end values you need to include, and append them to the output array:
$a = array(12,19,23);
$b = array(
range(11,15),
range(16,21),
range(22,26)
);
$c = array();
foreach ($a as $k => $cap) {
$start = $b[$k][0];
$finish = min($b[$k][count($b[$k])-1], $cap);
for ($i = $start; $i <= $finish; $i++) {
$c[] = $i;
}
}
print_r($c);
prints
Array
(
[0] => 11
[1] => 12
[2] => 16
[3] => 17
[4] => 18
[5] => 19
[6] => 22
[7] => 23
)
My solution is probably not the most efficient, but here goes:
$numbers = array(12,19,23);
$ranges = array(
array(11,15),
array(16,21),
array(22,26)
);
$output = array();
// Loop through each of the numbers and ranges:
foreach($numbers as $num) {
foreach($ranges as $r) {
if ($num >= $r[0] && $num <= $r[1]) {
// This is the correct range
// Array merge to append elements
$output = array_merge($output, range($r[0], $num));
break;
}
}
}
// Sort the numbers if you wish
sort($output, \SORT_NUMERIC);
print_r($output);
Produces:
Array
(
[0] => 11
[1] => 12
[2] => 16
[3] => 17
[4] => 18
[5] => 19
[6] => 22
[7] => 23
)

Explode txt file into multidimensional array

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:"
}
}

Php Array removing duplication and string conversion

hi i have output of an array as follow:
Array (
[0] => 66, 65, 64
[1] => 57
[2] => 66,23
[3] => 66
)
How can i remove duplication values and convert the collection into comma separated string? The unique output is 66,65,64,57,23. Thanks
Make use of array_unique() and array_reverse():
$array = Array (
0 => '66, 65, 64',
1 => '57',
2 => '66,23',
3 => '66',
);
$collection = array();
foreach($array as $numbers) {
$nums = explode(',', $numbers);
foreach($nums as $num) {
$collection[] = trim($num);
}
}
// unique and sort
$collection = array_unique($collection, SORT_NUMERIC);
// reverse it so that it can be descending order
$collection = array_reverse($collection);
print_r($collection);
which will output :
Array (
[0] => 66
[1] => 65
[2] => 64
[3] => 57
[4] => 23
)
you iterate through the array and add it to a final array by checking its values then implode to construct a string.
$array = Array (
0 => array(66, 65, 64),
1 => array(57),
2 => array(66,23),
3 => array( 66)
);
$final = array();
foreach ($array as $item) {
foreach ($item as $num) {
if (!in_array($num, $final)) $final[] = $num;
}
}
$str = implode(",", $final);
echo $str
well, the code is lil ugly...
$test = [
'0' => '66, 65',
'1' => '80', '66'
];
$temp = implode(',', array_map('trim', array_unique(explode(',', implode(',', $test)))));
print_r($test);
print_r($temp);
//output
Array (
[0] => 66, 65
[1] => 80
[2] => 66
)
66,65,80
Ok:
<?php
$array = array(
"66, 65, 64",
57,
"66,23",
66
);
function dosplit($a,$b) {
if (preg_match("/,/",$b)) {
$a = array_merge($a, preg_split('/\s*,\s*/', $b));
} else {
array_push($a, $b);
}
return $a;
}
$result = array_reduce($array, 'dosplit' ,array());
$array = array_unique($result);
The output is:
Array
(
[0] => 66
[1] => 65
[2] => 64
[3] => 57
[5] => 23
)
This might is useful for you:
$array = array(
"66, 65, 64 ",
"57",
"66,23",
"66",
);
echo "<pre>";
print_r($array);
//to make single line
foreach ($array as $val) {
$singleline.=$val . ",";
}
echo $singleline . "</br>";
//remove the "," end of the value
$endvlaue = rtrim($singleline, ",");
echo $endvlaue;
//make an array
$val = explode(",", $endvlaue);
echo "<pre>";
print_r($val);
echo "<pre>";
//make uniqu
$finalvalue = array_unique($val);
echo "<pre>";
//make , seperator
print_r(implode(",", $finalvalue));

String parsing in PHP

I am trying to parse a string in PHP:
-father_name "John" -father_weight 44.50
-kid >name "Marko" >age 12
-kid >name "Sevda" >age 17
-kid >name "Nathan" >age 19
There are two main FORMS:
Attributes (such as -father, -weight, -kid)
Sub-Attributes (such as >name, >age)
Note: Attributes are NOT FIXED and NOT ALWAYS SEPERATED BY single space
And their VALUES have two types:
String (like "Marko")
Int or Decimal (like 12.00)
OUTPUT would be:
$array['attributes'] = array('father_name ','father_weight ');
$array['attributes']['kid'][] = array('name' => "Marko", 'age' => 12);
$array['attributes']['kid'][] = array('name' => "Sevda", 'age' => 17);
$array['attributes']['kid'][] = array('name' => "Nathan", 'age' => 19);
It should return FORMS (attrs and sub-attrs) and VALUES SEPARATELY.
How can I parse this line in PHP cleverly?
Last Note: Solution I found for this: YAML.
Try with this:
function parse_attributes($string, $separators = array('-','>'), $level = 0){
$attributes = explode($separators[$level], $string);
$attrs = array();
$ret_arr = array();
foreach($attributes as $attribute){
if(!empty($attribute)){
$ex_attr = explode(' ',$attribute);
if(!empty($ex_attr[1])){
if(count($separators) > $level && strpos($attribute, $separators[$level+1])){
$ret = parse_attributes($attribute, $separators, $level+1);
array_push($ret_arr, $ret);
}
if (empty($ret_arr))
$attrs[$ex_attr[0]] = str_replace('"', '', $ex_attr[1]);
else
$attrs[$ex_attr[0]] = $ret_arr;
}
}
}
return $attrs;
}
Using:
$returned = parse_attributes('-father_name "John" -father_weight 44.50 -kid >name "Marko" >age 12 -kid >name "Sevda" >age 17 -kid >name "Nathan" >age 19');
print_r($returned);
Returns:
Array
(
[father_name] => John
[father_weight] => 44.50
[kid] => Array
(
[0] => Array
(
[name] => Marko
[age] => 12
)
[1] => Array
(
[name] => Sevda
[age] => 17
)
[2] => Array
(
[name] => Nathan
[age] => 19
)
)
)
And using:
echo($returned['kid'][0]['name']);
Returns:
Marko
NOTE: You can specify more separator array items, an item for each attribute level you have.
Hope this helps.
$output = array();
$input = explode('-', $input);
foreach ($input as $attribute) {
$attribute = explode('>', $attribute);
if (count($attribute) == 1) {
$attribute = explode(' ', trim($sub_attribute), 2);
$output[$attribute[0]] = eval($attribute[1]);
} else {
$attribute_name = trim($attribute[0]);
if (!isset($output[$attribute_name]) {
$output[$attribute_name] = array();
}
$sub_attribute_output = array();
for ($i = 1; $i < count($attribute); $i++) {
$sub_attribute = explode(' ', trim($attribute[$i]), 2);
$sub_attribute_output[$sub_attribute[0]] = eval($sub_attribute[1]);
}
$output[$attribute_name][] = $sub_attribute_output;
}
}

Categories