Get array from string in pattern - key1:val1,val2,..;key2:val1, - php

I would like to get from a string like this
color:blue,red;size:s
to an associative multiarray
[
color => [blue,red],
size => [s]
]
I tried with ([a-z]+):([a-z^,]+) but it's not enough; I don't know how to recursive it or something.

I wouldn't use regular expressions for something like this. Instead use explode() several times.
<?php
$str = 'color:blue,red;size:s';
$values = explode(';', $str);
$arr = [];
foreach($values as $val) {
$parts = explode(':', $val);
$arr[$parts[0]] = explode(',', $parts[1]);
}
Output:
Array
(
[color] => Array
(
[0] => blue
[1] => red
)
[size] => Array
(
[0] => s
)
)

$dataText = 'color:blue,red;size:s';
$data = explode(';', $dataText);
$outputData = [];
foreach ($data as $item){
$itemData = explode(':', $item);
$outputData[$itemData[0]] = explode(',', $itemData[1]);
}
print_r('<pre>');
print_r($outputData);
print_r('</pre>');

With regex is not so simple like explode, but you can try this...
$re = '/(\w+)\:([^;]+)/';
$str = 'color:blue,red;size:s';
preg_match_all($re, $str, $matches);
// Print the entire match result
$result = array();
$keys = array();
for($i = 1; $i < count($matches); $i++) {
foreach($matches[$i] as $k => $val){
if($i == 1) {
$result[$val] = array();
$keys[$k] = $val;
} else {
$result[$keys[$k]] = $val;
}
}
}
echo '<pre>';
print_r($result);
echo '</pre>';
result
Array
(
[color] => blue,red
[size] => s
)

Related

Split string with only one delimiting character into key-value pairs [duplicate]

This question already has answers here:
Convert backslash-delimited string into an associative array
(4 answers)
Closed 7 months ago.
I have a colon-delimited string like this:
"Part1:Part2:Part3:Part4"
With explode I can split the string into an array:
echo '<pre>';
print_r(explode(":", "Part1:Part2:Part3:Part4"));
echo '</pre>';
Output:
Array
(
[0] => Part1
[1] => Part2
[2] => Part3
[3] => Part4
)
But I need associative array elements like this:
Array
(
[Part1] => Part2
[Part3] => Part4
)
UPDATE
echo '<pre>';
list($key, $val) = explode(':', 'Part1:Part2:Part3:Part4');
$arr= array($key => $val);
print_r($arr);
echo '</pre>';
Result:
Array
(
[Part1] => Part2
)
Alternative solution using only array_* functions.
Collect all values that are going to be keys for the resultant array.
Collect all values that are going to be actual values for the resultant array.
Combine both using array_combine().
Snippet:
<?php
$str = "Part1:Part2:Part3:Part4";
$res = array_combine(
array_map(fn($v) => $v[0], array_chunk(explode(':',$str),2)),
array_map(fn($v) => $v[1], array_chunk(explode(':',$str),2))
);
Using a for loop, you could also use the modulo operator % and create the key in the if part.
The if clause will be true for the first item having the key first and then the value in the else part, toggeling the keys and the values.
$str = "Part1:Part2:Part3:Part4";
$parts = explode(':', $str);
$result = [];
for ($i = 0; $i < count($parts); $i++) {
$i % 2 === 0 ? $k = $parts[$i] : $result[$k] = $parts[$i];
}
print_r($result);
Output
Array
(
[Part1] => Part2
[Part3] => Part4
)
See a php demo
Try this
$string = "Part1:Part2:Part3:Part4";
$arr = explode(":", $string);
$key = "";
$i = 0;
$newArray = [];
foreach($arr as $row){
if($i == 0){
$key = $row;
$i++;
} else {
$newArray[$key] = $row;
$i = 0;
}
}
echo "<pre>";
print_r($newArray);
echo "</pre>";

php ldap retrieve ou value of dn

I'm trying below code to get the value as ou=grp1 from
dn: uid=john,ou=grp1,ou=people,dc=site,dc=com , but not understanding how to retrieve.
here is the code:
<?php
function pairstr2Arr ($str, $separator='=', $delim=',') {
$elems = explode($delim, $str);
foreach( $elems as $elem => $val ) {
$val = trim($val);
$nameVal[] = explode($separator, $val);
$arr[trim(strtolower($nameVal[$elem][0]))] = trim($nameVal[$elem][1]);
}
return $arr;
}
// Example usage:
$string = 'uid=john,ou=grp1,ou=people,dc=site,dc=com';
$array = pairstr2Arr($string);
echo '<pre>';
print_r($array);
echo '</pre>';
?>
output:
<pre>Array
(
[uid] => john
[ou] => people //here I want to get output ou=grp1,how?
[dc] => com
)
</pre>
find output here: https://ideone.com/rE6eaH
Because of ou and dc might have multiple values, you should store those values in array. Thanks to that you can have easy access to data. Check out this code:
<?php
function pairstr2Arr ($str, $separator='=', $delim=',') {
$elems = explode($delim, $str);
$arr = array();
foreach( $elems as $elem => $val ) {
$val = trim($val);
$tempArray = explode($separator, $val);
if(!isset($arr[trim($tempArray[0])]))
$arr[trim($tempArray[0])] = '';
$arr[trim($tempArray[0])] .= $tempArray[1].';';
}
foreach($arr as $key => $value)
{
$explodedValue = explode(';', $value);
if(count($explodedValue) > 2)
{
$arr[$key] = $explodedValue;
unset($arr[$key][count($explodedValue) - 1]);
}
else
$arr[$key] = substr($arr[$key], 0, -1);
}
return $arr;
}
// Example usage:
$string = 'uid=john,ou=grp1,ou=people,dc=site,dc=com';
$array = pairstr2Arr($string);
echo '<pre>';
print_r($array);
echo '</pre>';
?>
Result is:
Array
(
[uid] => john
[ou] => Array
(
[0] => grp1
[1] => people
)
[dc] => Array
(
[0] => site
[1] => com
)
)

How to put comma separated string in two different arrays?

I want to put my string (separated by comma) in 2 different arrays.
$str = 1,First,2,Second,3,Third,4,Forth,5,Fifth
My goal is to group the numbers and the text.
$number = {1,2,3,4,5)
$text = {first, second, third, forth, fifth}
I tried to use explode(), but I only be ale to create a single array.
This should work for you:
First explode() your string by a comma. Then you can array_filter() the numbers out. And at the end you can simply take the array_diff() from the $arr and the $numbers array.
<?php
$str = "1,First,2,Second,3,Third,4,Forth,5,Fifth";
$arr = explode(",", $str);
$numbers = array_filter($arr, "intval");
$text = array_diff($arr, $numbers);
?>
You can use explode() and array_map() over the results:
$str = '1,First,2,Second,3,Third,4,Forth,5,Fifth';
array_map(function($item) use (&$numbers, &$strings) {
if(is_numeric($item)) {
$numbers []= $item;
} else {
$strings []= $item;
}
}, explode(',', $str));
var_dump($numbers, $strings);
<?php
$str = array(1,'First',2,'Second',3,'Third',4,'Forth',5,'Fifth');
$letters =array();
$no = array();
for($i=0;$i<count($str);$i++){
if($i%2 ==0){
$letters[] = $str[$i];
}else{
$no[] = $str[$i];
}
}
print_r($no);
print_r($letters);
?>
May be this can help you
$str = '1,First,2,Second,3,Third,4,Forth,5,Fifth';
$array = explode(',',$str);
$number = array();
$string = array();
foreach($array as $val)
{
if(is_numeric($val))
{
$number[] = $val;
}
elseif(!is_numeric($val))
{
$string[] = $val;
}
}
echo $commNum = implode(',',$number); // These are strings
echo '<br/>'.$commStr = implode(',',$string); // These are strings
echo '<pre>';
print_r($number); // These are arrays
echo '<pre>';
print_r($string); // These are arrays
This should work for you.
$str = '1,First,2,Second,3,Third,4,Forth,5,Fifth';
$result = explode(',',$str);
$number = array();
$text = array();
foreach(explode(',',$str) as $key => $value){
if($key % 2 == 1){
$text[] = $value;
}elseif($key % 2 == 0){
$number[] = $value;
}
}
print_r($number);//Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 )
print_r($text);//Array ( [0] => First [1] => Second [2] => Third [3] => Forth [4] => Fifth )
and if your array is not consistent in this manner then some of these above answers are well suited for you like of Rizier123,hek2mgl,& Sunil's one
I'm updating my answer for your correspondent comments over Adrian
foreach(explode(',',$str) as $key => $value){
if(is_numeric($value)){
$number[] = $value;
}else{
$text[] = $value;
}
}
You can use explode, but you need apply some filter in this case is is_numeric:
<?php
$str = '1,First,2,Second,3,Third,4,Forth,5,Fifth, erewwrw , 6 ';
$array = explode(',', $str);
$array_numbers = array();
$array_letters = array();
for($i = 0; $i < count($array); $i++) {
if(is_numeric(trim($array[$i]))) {
$array_numbers[] = trim($array[$i]);
} else {
$array_letters[] = trim($array[$i]);
}
}
print_r($array_numbers);
print_r($array_letters);
?>
Output:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
Array
(
[0] => First
[1] => Second
[2] => Third
[3] => Forth
[4] => Fifth
)
Assuming that your string contains number followed by string and so on,
following should be the solution.
Create two blank arrays: $numbers and $strings.
Just loop over the array and get even and odd elements.
Even elements should go to numbers array and odd elements should go to strings array.
$str = '1,First,2,Second,3,Third,4,Forth,5,Fifth';
$numbers = array();
$strings = array();
$temp = explode(',', $str);
$i=0;
foreach ($temp as $e) {
if ($i%2) {
$strings[] = $e;
}
else {
$numbers[] = $e;
}
++$i;
}
echo '<pre>';
print_r($numbers);
echo '</pre>';
echo '<pre>';
print_r($strings);
echo '</pre>';

Covert flat array to Nested Array in PHP

Given the following input:
array('one/two/3',
'one/four/0/5',
'one/four/1/6',
'one/four/2/7',
'eight/nine/ten/11')
How can I convert it into this:
array(
'one': array(
'two': 3,
'four': array(5,6,7)
)
'eight': array(
'nine': (
'ten':11
)
}
)
$input = array ('one/two/3',
'one/four/0/5',
'one/four/1/6',
'one/four/2/7',
'eight/nine/ten/11');
$result = array ();
foreach ($input as $string) {
$data = array_reverse(explode('/', $string));
$tmp_array = array ();
foreach ($data as $val) {
if (empty($tmp_array)) {
$tmp_array = $val;
} else {
$tmp = $tmp_array;
$tmp_array = array ();
$tmp_array[$val] = $tmp;
}
}
$result = array_merge_recursive($result, $tmp_array);
}
echo "<pre>";
print_r($result);
echo "</pre>";
Output:
Array
(
[one] => Array
(
[two] => 3
[four] => Array
(
[0] => 5
[1] => 6
[2] => 7
)
)
[eight] => Array
(
[nine] => Array
(
[ten] => 11
)
)
)
It would be nice if we saw what you have tried.
$my_array = array('one/two/3',
'one/four/0/5',
'one/four/1/6',
'one/four/2/7',
'eight/nine/ten/11');
$result= array();
foreach ($my_array as $val) {
$ref = & $result;
foreach (explode("/", $val) as $val) {
if (!isset($ref[$val])) {
$ref[$val] = array();
}
$ref = & $ref[$val];
}
$ref = $val;
}
var_dump($result);

preg_match a "shortcode" to create an array with semantic array keys

How would I preg_match the following piece of "shortcode" so that video and align are array keys and their values are what is with in the quotes?
[video="123456" align="left"/]
Here is another approach using array_combine():
$str = '[video="123456" align="left"/][video="123457" align="right"/]';
preg_match_all('~\[video="(\d+?)" align="(.+?)"/\]~', $str, $matches);
$arr = array_combine($matches[1], $matches[2]);
print_r() output of $arr:
Array
(
[123456] => left
[123457] => right
)
$string='[video="123456" align="left"/]';
$string= preg_replace("/\/|\[|\]/","",$string);
$s = explode(" ",$string);
foreach ($s as $item){
list( $tag, $value) = explode("=",$item);
$array[$tag]=$value;
}
print_r($array);
Alternate solution with named parameters:
$str = '[video="123456" align="left"/][video="123457" align="right"/]';
$matches = array();
preg_match_all('/\[video="(?P<video>\d+?)"\salign="(?P<align>\w+?)"\/\]/', $str, $matches);
for ($i = 0; $i < count($matches[0]); ++ $i)
print "Video: ".$matches['video'][$i]." Align: ".$matches['align'][$i]."\n";
You could also reuse the previous array_combine solution given by Alix:
print_r(array_combine($matches['video'], $matches['align']));
I don't think there's any (simple) way to do it using a single regex, but this will work in a fairly general way, picking out the tags and parsing them:
$s = 'abc[video="123456" align="left"/]abc[audio="123456" volume="50%"/]abc';
preg_match_all('~\[([^\[\]]+)/\]~is', $s, $bracketed);
$bracketed = $bracketed[1];
$tags = array();
foreach ($bracketed as $values) {
preg_match_all('~(\w+)\s*=\s*"([^"]+)"~is', $values, $pairs);
$dict = array();
for ($i = 0; $i < count($pairs[0]); $i++) {
$dict[$pairs[1][$i]] = $pairs[2][$i];
}
array_push($tags, $dict);
}
//-----------------
echo '<pre>';
print_r($tags);
echo '</pre>';
Output:
Array
(
[0] => Array
(
[video] => 123456
[align] => left
)
[1] => Array
(
[audio] => 123456
[volume] => 50%
)
)

Categories