PHP - group every 2 parts of a string together in an array - php

I have a long string that is constructed like this:
randomstring number randomstring number randomstring number
I need to group these random strings and numbers together so that I get an array like this:
array = [[randomstring, number], [[randomstring, number], [randomstring, number]]
I don't know the amount of spaces between the strings and numbers. Any suggestions?
UPDATE
Since Edwin Moller's answer I'm now left with this array:
Array (46) {
[0] =>
array(2) {
[0]=>
string(20) "string"
[1]=>
string(7) "number"
}
[1]=>
array(2) {
[0]=>
string(5) ""
[1]=>
string(7) ""
}
[2] =>
array(2) {
[0]=>
string(10) ""
[1]=>
string(11) ""
}
[3] =>
array(2) {
[0]=>
string(10) ""
[1]=>
string(11) ""
}
[4] =>
array(2) {
[0]=>
string(10) ""
[1]=>
string(11) ""
}
The array elements that have 2 empty elements themselves need to be removed.
I'll leave it with this solution. It's not elegant at all, but I don't know what these 'empty' strings are. It doesn't respond to whitespace, space, any character test so I used the strlen() function:
$str = preg_replace('!\s+!', ' ', $longstring);
$parts = explode(" ", $str);
$nr = count($parts);
for ($i = 0; $i < $nr; $i = $i + 2) {
if(strlen($parts[$i]) > 20) { // ugly, but it works for now..
$tmp[] = [$parts[$i], $parts[$i + 1]];
}
}
// unsetting these elements because they are longer than 30
unset($tmp[0]);
unset($tmp[1]);
unset($tmp[2]);

$longstring = "randomstring1 1001 randomstring2 205 randomstring3 58";
// First, take care of the multiple spaces.
$str = preg_replace('/\s+/', ' ', $longstring);
// split in parts on space
$parts = explode(" ",$str);
$nr = count($parts);
$tmp = array();
for ($i=0; $i<$nr; $i=$i+2){
$tmp[] = array($parts[$i], $parts[$i+1]);
}
echo "<pre>";
print_r($tmp);
echo "</pre>";
You might want to make sure it is an even number. (check $nr).
Edit: OP says you have some empty elements in the array $parts.
I don't know what causes that, possibly some encoding issues, not sure without having the original material (string).
A wild guess: Try to utf8_decode the original string, then do the preg_replace, and then print_r.
Like this:
$longstring = "randomstring1 1001 randomstring2 205 randomstring3 58";
$longstring = utf8_decode($longstring);
$str = preg_replace('/\s+/', ' ', $longstring);
$parts = explode(" ",$str);
echo "<pre>";
print_r($parts);
echo "</pre>";

explode string and then check it like this
Online Demo
$str="randomstring number randomstring number randomstring number";
$exp=explode(" ",$str);
for($i=0;$i<count($exp);$i++)
{
if(trim($exp[$i])=="")
continue;
$result[]=array(0=>$exp[$i],1=>$exp[$i+1]);
$i++;
}
var_dump($result);

Try the following
//Our string
$string = "randomstring 11 randomstring 22 randomstring 33";
//Split them up if they have MORE THAN ONE space
$firstSplit = preg_split('/\s\s+/', $string);
//Set up a new array to contain them
$newArray = array();
//For each of the ones like "randomstring 11"
foreach($firstSplit as $key => $split){
//Split them if they have ONE OR MORE space
$secondSplit = preg_split('/\s+/', $split);
//Add them to the array
//Note: change this part to structure the array however you'd like
$newArray[$key]["string"] = $secondSplit[0];
$newArray[$key]["integer"] = $secondSplit[1];
}
The comments should explain well enough what is happening here, it will leave you with the following:
array (size=3)
0 =>
array (size=2)
'string' => string 'randomstring' (length=12)
'integer' => string '11' (length=2)
1 =>
array (size=2)
'string' => string 'randomstring' (length=12)
'integer' => string '22' (length=2)
2 =>
array (size=2)
'string' => string 'randomstring' (length=12)
'integer' => string '33' (length=2)

I do not know if it is the shortest way but i would say your issue can be consist of this steps
1- convert the multi spaces to one space
2- explode the big string to one array has all the sub string
3- group the elements by loop over the big array
<?php
$str = 'randomstring1 number1 randomstring2 number2 randomstring3 number3';
//remove the spaces and put all the element in one array
$arr = explode(' ', $str);
$space = array('');
$arr = array_values(array_diff($arr, $space));
//now loop over the array and group elements
$result = $temArr = array();
foreach($arr as $index => $element){
if($index % 2){//second element (number)
$temArr[] = $element;
$result[] = $temArr;
$temArr = array();
}else{//first element (randomstring)
$temArr[] = $element;
}
}
//print the result
var_dump($result);die;
?>

First split by 2 or more spaces, then split those groups by the single space.
Try this:
$input = 'randomstring1 number1 randomstring2 number2 randomstring3 number3';
$groups = preg_split("/[\s]{2,}/", $input );
$result = array_map(function($i){
return explode(' ', $i);
}, $groups);
Which gets me this result:
array(3) {
[0] = array(2) {
[0] = string(13) "randomstring1"
[1] = string(7) "number1"
}
[1] = array(2) {
[0] = string(13) "randomstring2"
[1] = string(7) "number2"
}
[2] = array(2) {
[0] = string(13) "randomstring3"
[1] = string(7) "number3"
}
}

Related

Convert a string to a multidimensional array

How can I convert the string test[1][2][3][4][5] to a multidimensional PHP array like:
array(1 => array(2 => array( 3 => array( 4 => array(5 => array()))));
If I understood your question correctly, you're asking to convert the string "test[1][2][3][4][5]" to array(1 => array(2 => array( 3 => array( 4 => array(5 => array()))));
First of all, people usually use the short array() notation, which is just [].
Second, why use strings, when you can just type
$test[1][2][3][4][5] = [];
to get what you want.
If you really want strings, you can do it in several ways, one of which is:
function makeArrayFromString($string, &$name)
{
$namePosEnd = strpos($string, '['); // name ends when first [ starts
if (!$namePosEnd) return false; // didn't find [ or doesn't start with name
$name = substr($string, 0, $namePosEnd);
$dimensionKeys = [];
$result = preg_match_all('/\[([0-9]+)\]/', $string, $dimensionKeys); // get keys
if (!$result) return false; // no matches for dimension keys
$dimensionKeys = array_reverse($dimensionKeys[1]);
$multiArray = [];
foreach ($dimensionKeys as $key)
{
$key = (int)$key; // we have string keys, turn them to integers
$temp = [];
$temp[$key] = $multiArray;
$multiArray = $temp;
}
return $multiArray;
}
$string = 'test[1][2][3][4][5]';
$name = '';
$multiArray = makeArrayFromString($string, $name);
if ($multiArray === false)
exit('Error creating the multidimensional array from string.');
$$name = $multiArray; // assign the array to the variable name stored in $name
var_dump($test); // let's check if it worked!
Outputs:
array(1) {
[1]=>
array(1) {
[2]=>
array(1) {
[3]=>
array(1) {
[4]=>
array(1) {
[5]=>
array(0) {
}
}
}
}
}
}
Keep in mind that I didn't add any checks if the $name string satisfies the PHP variable naming rules. So you might get an error if you do something like 111onetest[1][2][3][4][5], as variable names in PHP can't start with a number.

Transforming an array value into a new array without losing any characters

I have an array that looks like this:
Array
(
[basisprijs] => 17,00
[basisstaffel] =>
3-10:17;
10-20:14;
20-30:12;
30-40:10;
40-50:7,50;
50-60:6,50;
60-110:6;
[minimaalformaat] => 10x3
[maximaalformaat] => 120x5000
[breedte] => 12
[hoogte] => 4
[aantal] => 1
[Lijmlaag] => Wit(prijsberekening)+($m2*4);
)
I want to create a new array from [basisstaffel] with after each ; a new line starting, so the desired end result would be:
Array
(
[0] = > 3-10:17;
[1] = > 10-20:14;
[2] = > 20-30:12;
[3] = > 30-40:10;
[4] = > 40-50:7,50;
[5] = > 50-60:6,50;
[6] = > 60-110:6;
)
How can I do that? Using explode on the ; makes me lose that part of the value. So is there another way?
The first array is called $productarray
You could just use the explode function and after that, do a foreach loop and add the ';' symbol again, like so:
$newArray=array();
$myArray=array();
$myArray['basisprijs'] = '17,00';
$myArray['basisstaffel'] ='3-10:17;10-20:14;20-30:12;30-40:10;40-50:7,50;50-60:6,50;60-110:6';
$myArray['minimaalformaat'] = '10x3';
$myArray['maximaalformaat'] = '120x5000';
$myArray['breedte'] = '12';
$myArray['hoogte'] = '4';
$myArray['aantal'] = '1';
$myArray['Lijmlaag'] = 'Wit(prijsberekening)+($m2*4)';
$basisstafel=$myArray['basisstaffel'];
$tmp = explode(";", $basisstafel);
foreach ($tmp as $ind){
$newArray[]=$ind.';';
}
echo "<pre>";
print_r($newArray);
echo "</pre>";
You can use preg_split and use the PREG_SPLIT_DELIM_CAPTURE flag.
This will return matches array with delimiter = 0, match = 1
https://www.php.net/manual/en/function.preg-split.php
PREG_SPLIT_DELIM_CAPTURE
If this flag is set, parenthesized expression in the delimiter pattern will be captured and returned as well.
<?php
$productArray = [
'basisprijs' => '17,00',
'basisstaffel' =>'
3-10:17;
10-20:14;
20-30:12;
30-40:10;
40-50:7,50;
50-60:6,50;
60-110:6;',
'minimaalformaat' => '10x3',
'maximaalformaat' => '120x5000',
'breedte' => 12,
'hoogte' => 4,
'aantal' => 1,
'Lijmlaag' => 'Wit(prijsberekening)+($m2*4);'
];
$basisstaffel = explode(";", rtrim($productArray['basisstaffel'], ';'));
var_dump($basisstaffel);
Result : array(8) { [0]=> string(14) " 3-10:17" [1]=> string(14) " 10-20:14" [2]=> string(14) " 20-30:12" [3]=> string(14) " 30-40:10" [4]=> string(16) " 40-50:7,50" [5]=> string(16) " 50-60:6,50" [6]=> string(14) " 60-110:6" }
?>
It looks like you have newlines after ; so you can preg_split by whitespace:
$result = preg_split('/\s+/', $input['basisstaffel']);
To avoid first empty item add PREG_SPLIT_NO_EMPTY flag:
$result = preg_split('/\s+/', $input['basisstaffel'], -1, PREG_SPLIT_NO_EMPTY);
Or simply use explode with \n or \r\n\ (you must know type of newlines you have):
$result = explode("\n", $input['basisstaffel']);

Expload Separator Array

I have an code from database like
$exp = ukuran:33,34,35;warna:putih,hitam;
i want to make an array like
$ukuran = array("33", "34", "35");
$warna = array("putih","hitam");
i have try to use explode but i have trouble result.
explode(";",$exp);
the result like
Array
(
[0] => ukuran:33,34,35
[1] => warna:putih,hitam
[2] =>
)
Anyone can help me, how to explode this case please?
$string = 'ukuran:33,34,35;warna:putih,hitam;';
$string = str_replace(['ukuran:', 'warna:'], '', $string);
$exploded = explode(';', $string);
$ukuran = explode(',', $exploded[0]);
$warna = explode(',', $exploded[1]);
If you want to do it dynamically you can't create variables but you can create an array with the types as keys:
$string = 'ukuran:33,34,35;warna:putih,hitam;';
$exploded = explode(';', $string);
$keysAndValues = [];
foreach($exploded as $exp) {
if (strlen($exp) > 0) {
$key = substr($exp, 0, strpos($exp, ':' ) );
$values = substr($exp, strpos($exp, ':' ) + 1, strlen($exp) );
$values = explode(',', $values);
$keysAndValues[$key] = $values;
}
}
This will output:
array (size=2)
'ukuran' =>
array (size=3)
0 => string '33' (length=2)
1 => string '34' (length=2)
2 => string '35' (length=2)
'warna' =>
array (size=2)
0 => string 'putih' (length=5)
1 => string 'hitam' (length=5)
Call them like this:
var_dump($keysAndValues['ukuran']);
var_dump($keysAndValues['warna']);
I would personally say continue as you are, then with your array in your result, loop through each item in the array and store it like so
$string = 'ukuran:33,34,35;warna:putih,hitam;';
$exploded = explode(';',$string);
$master = [];
foreach($exploded as $key => $foo){
$namedKey = explode(':',$foo);
$bar = substr($foo, strpos($foo, ":") + 1); //Get everything after the ; character
$master[$namedKey[0]] = explode(",",$bar);
}
This should return a result something along the lines of
array(3) {
["ukuran"]=>
array(3) {
[0]=>
string(2) "33"
[1]=>
string(2) "34"
[2]=>
string(2) "35"
}
["warna"]=>
array(2) {
[0]=>
string(5) "putih"
[1]=>
string(5) "hitam"
}
}
You can use regex to match words and numbers separate.
Then use array_filter to remove the empty values.
$exp = "ukuran:33,34,35;warna:putih,hitam";
Preg_match_all("/(\d+)|([a-zA-Z]+)/", $exp, $matches);
Unset($matches[0]);
$matches[1] = array_filter($matches[1]);
$matches[2] = array_filter($matches[2]);
Var_dump($matches);
https://3v4l.org/cREn7
Actually there are many ways to do what you want, But If I were you then I'll try this way :)
<?php
$exp = 'ukuran:33,34,35;warna:putih,hitam';
$result = explode(';',$exp);
foreach($result as $k=>$v){
$key_value = explode(':',$v);
// this line will help your to treat your $ukuran and $warna as array variable
${$key_value[0]} = explode(',',$key_value[1]);
}
print '<pre>';
print_r($ukuran);
print_r($warna);
print '</pre>';
?>
DEMO: https://3v4l.org/BAaCT

How to Seperate Array with equals to and create single array

Hi I am working on very complex array operations.
I have $temp variable which stores pipe separated string like Height=10|Width=20
I have used explode function to convert into array and get specific output.
Below code i have try :
$product_attributes = explode("|",$temp)
//below output i get after the explode.
$product_attributes
Array(
[0]=>Height=10
[1]=>width=20
)
But i want to parse this array to separate one.
My expected output :
Array (
[0]=>Array(
[0] => Height
[1] => 10
)
[1]=>Array(
[0]=>Width
[1]=>20
)
)
Which function i need to used to get the desire output ?
Before downvoting let me know if i have made any mistake
You could try the below code. I've tested this and it outputs the result you've shown in your post.
$temp = 'Height=10|Width=20';
$product_attributes = explode('|', $temp);
$product_attributes2 = array();
foreach ($product_attributes as $attribute) {
$product_attributes2[] = explode('=', $attribute);
}
print_r($product_attributes2);
Try Below code
<?php
$temp = "Height=10|Width=20";
$product_attributes = explode("|", $temp);
foreach ($product_attributes as $k => $v) {
$product_attributes[$k] = explode('=', $v);
}
echo '<pre>';
print_r($product_attributes);
?>
check running answer here
Process your result by this:
$f = function($value) { return explode('=', $value); }
$result = array_map($f, $product_attributes);
One more option is to split the values in to one array and then build them from there.
$str = "Height=10|Width=20";
$arr = preg_split("/\||=/", $str);
$arr2= array();
$j=0;
for($i=0;$i<count($arr);$i++){
$arr2[$j][]= $arr[$i];
$arr2[$j][]= $arr[$i+1];
$i++;
$j++;
}
var_dump($arr2);
The output will be:
$arr = array(4){
0 => Height
1 => 10
2 => Width
3 => 20
}
$arr2 = array(2) {
[0]=>
array(2) {
[0]=>
string(6) "Height"
[1]=>
string(2) "10"
}
[1]=>
array(2) {
[0]=>
string(5) "Width"
[1]=>
string(2) "20"
}
}

Create new multidimensional array from flat array - directory paths - PHP

Hope someone can point me in the right direction here...
I've got directory paths and partial file outputs form a unix grep. I have a flat array from these outputs. Now I'd like to do a bit of PHP magic to turn this flat array into a more hierarchical multidimensional array for more refined user output
Current array;
array(7) {
[0]=>
string(160) "/home/user/data/section1/dir1/20120107/filename.txt:random text after the colon"
[1]=>
string(160) "/home/user/data/section1/dir1/20120108/filename.txt: More random text after the colon"
[2]=>
string(160) "/home/user/data/section1/dir2/20120107/filename.txt: More random text after the colon"
[3]=>
string(160) "/home/user/data/section1/dir2/20120108/filename.txt: More random text after the colon"
[4]=>
string(160) "/home/user/data/section1/dir3/20120107/filename.txt: More random text after the colon"
[5]=>
string(160) "/home/user/data/section1/dir3/20120106/filename.txt: More random text after the colon"
[6]=>
string(160) "/home/user/data/section1/dir3/20120108/filename.txt: More random text after the colon"
}
What i would really like
array(1) {
array(3) {
["dir"]=>
string(4) "dir1"
["date"]=>
string(8) "20120107"
["text"]=>
array (2) {
[0]=>
string(160) "random text after the colon"
[1]=>
string(160) "More random text after the colon"
}
}
array(3) {
["dir"]=>
string(4) "dir1"
["date"]=>
string(8) "20120108"
["text"]=>
array (2) {
[0]=>
string(160) "More random text after the colon"
[1]=>
string(160) "More random text after the colon"
}
}
array(3) {
["dir"]=>
string(4) "dir2"
["date"]=>
string(8) "20120107"
["text"]=>
array (2) {
[0]=>
string(160) "More random text after the colon"
[1]=>
string(160) "More random text after the colon"
}
}
}
I have tried a lot of foreach's, SPL iterator methods, but i'm just not coming out trumps. Looking for any guidance.
Thanks all
This code (using a for loop):
<?php
$data[] = "/home/user/data/section1/dir1/20120107/filename.txt:random text after the colon";
$data[] = "/home/user/data/section1/dir1/20120108/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir2/20120107/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir2/20120108/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir3/20120107/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir3/20120106/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir3/20120108/filename.txt: More random text after the colon";
for($i = 0; $i < count($data); $i++) {
$data[$i] = str_replace('/home/user/data/section1/','',$data[$i]);
$tmp = explode('/', $data[$i]);
$newData[$i] = array(
'dir' => $tmp[0],
'date' => $tmp[1]
);
$tmp = explode(':', $tmp[2]);
$newData[$i]['fileName'] = $tmp[0];
$newData[$i]['text'] = $tmp[1];
}
print_r($newData);
?>
Or this code (using a foreach loop):
<?php
$data[] = "/home/user/data/section1/dir1/20120107/filename.txt:random text after the colon";
$data[] = "/home/user/data/section1/dir1/20120108/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir2/20120107/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir2/20120108/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir3/20120107/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir3/20120106/filename.txt: More random text after the colon";
$data[] = "/home/user/data/section1/dir3/20120108/filename.txt: More random text after the colon";
foreach($data as $d) {
$tmp = explode('/', str_replace('/home/user/data/section1/','',$d));
$tmp2 = explode(':', $tmp[2]);
$newData[] = array(
'dir' => $tmp[0],
'date' => $tmp[1],
'filename' => $tmp2[0],
'text' => $tmp2[1]
);
}
print_r($newData);
?>
Outputs:
Array
(
[0] => Array
(
[dir] => dir1
[date] => 20120107
[fileName] => filename.txt
[text] => random text after the colon
)
[1] => Array
(
[dir] => dir1
[date] => 20120108
[fileName] => filename.txt
[text] => More random text after the colon
)
============ more data here ============
[6] => Array
(
[dir] => dir3
[date] => 20120108
[fileName] => filename.txt
[text] => More random text after the colon
)
)
Explode each string of path with "/".You will get an array after that.Then push required element in the array.
Make a foreach over the first array and preg_match() the elements for the informations you want to extract from each string.
foreach( $firstArray => $strElement )
{
$newArray[] = array();
if( preg_match( "~(?<=section1/)[.-\w]*~i", $strElement, $astrMatches) >= 1 )
$newArray['dir'] = $astrMatches[0];
...etc...
}
function magic($array_of_strings)
{
define('REGEX','_^/home/user/data/section1/(dir\d+)/(\d+)/filename.txt:(.*)$_');
$ret_array = array();
foreach($array_of_strings as $string) {
if (preg_match(REGEX, $string, $matches)) {
$ret_array []= array(
'dir'=>$matches[1],
'date'=>$matches[2],
'text'=>$matches[3],
);
}
}
return $ret_array;
}
Ok this will do the job, you can change the directory structure as much as you like as long as the the last two directories keep the same order /dir/date.
You can add as many strings as you like to the text section of the array by seperating them with multiple colons after the URL. e.g. /blah/dir/date/filename.txt : string 1 : string 2.
Your original array must be called $array.
Enjoy:
foreach ($array as $string) {
$temp = array();
$temp["strings"] = explode(':', $string); //Convert the string into an array using `:` as a seperator
$temp["path"] = explode('/', $temp["strings"][0]); //Convert the url into an array using `/` as a seperator (each directory is it's own entry)
$path_count = count($temp["path"]); //Count number of directories in the url
$output = array(
"dir" => $temp["path"][$path_count - 3],
"date" => $temp["path"][$path_count - 2],
"text" => array()
);
foreach ($temp["strings"] as $index => $value) { //Loop through and add any additional text to array
if ($index) {
array_push($output["text"], trim($value));
}
}
print_r($output);
}
Thanks all for the input and scripts. I have actually learned quite a bit about massaging data into multidimensional arrays from these scripts. Unfortunately, none of them worked out exactly as i wanted. One thing i've learned researching this issue, is, 'is there another way to present the data?' and in this case i found it. A shell script, to search all files, output the filename, and then the relevant text.
find /home/user/data/section1 -name 'filename.txt' | xargs grep -il texttxet |
while read file
do
echo "$file"
grep -i -A 4 texttxet "$file"
done
File:/home/user/data/section1/dir1/20120107/filename.txt
line1
line2
line3
File:/home/user/data/section1/dir1/20120108/filename.txt
line1
line2
File:/home/user/data/section1/dir2/20120108/filename.txt
line1
line2
I can easily get this info in an array from this point. Thanks all again

Categories