PHP - split String in Key/Value pairs - php

I have a string like this:
key=value, key2=value2
and I would like to parse it into something like this:
array(
"key" => "value",
"key2" => "value2"
)
I could do something like
$parts = explode(",", $string)
$parts = array_map("trim", $parts);
foreach($parts as $currentPart)
{
list($key, $value) = explode("=", $currentPart);
$keyValues[$key] = $value;
}
But this seems ridiciulous. There must be some way to do this smarter with PHP right?

If you don't mind using regex ...
$str = "key=value, key2=value2";
preg_match_all("/([^,= ]+)=([^,= ]+)/", $str, $r);
$result = array_combine($r[1], $r[2]);
var_dump($result);

<?php parse_str(str_replace(", ", "&", "key=value, key2=value2"), $array); ?>

if you change your string to use & instead of , as the delimiter, you can use parse_str()

If you can change the format of the string to conform to a URL query string (using & instead of ,, among other things, you can use parse_str. Be sure to use the two parameter option.

Here's a single command solution using array_reduce formatted in multple lines for readability:
<?php
$str = "key=value, key2=value2";
$result = array_reduce(
explode(',', $str),
function ($carry, $kvp) {
list($key, $value)=explode('=', $kvp);
$carry[trim($key)]=trim($value);
return $carry;
}, []);

Related

preg_replace php to replace repeated characters

So I have a list of values like that goes like this:
values: n,b,f,d,e,b,f,ff`
I want to use preg_replace() in order to remove the repeated characters from the list of values (it will be inserted to a MySQL table). b and f are repeated. ff should not count as f because it's a different value. I know that \b \b will be used for that. I am not sure on how to take out the repeated b and f values as well as the , that precedes each value.
If the list is in a string looking like the example above, a regex is overkill. This does it just as well;
$value = implode(',', array_unique(explode(',', $value)));
I agree with other commenters that preg_replace is not the way to go; but, since you ask, you can write:
$str = preg_replace('/\b(\w+),(?=.*\b\1\b)/', '', $str);
That will remove all but the last instance of a given list-element.
No need for regex for this:
join(",", array_unique(split(",", $values)))
If this list you're dealing with is a simple string, a possible solution would be like this:
function removeDuplicates($str) {
$arr = explode(',', $str);
$arr = array_unique($arr);
return implode(',', $arr);
}
$values = removeDuplicates('n,b,f,d,e,b,f,ff'); // n,b,f,d,e,ff
$str = "values: n,b,f,d,e,b,f,ff";
$arr = array();
preg_match("/(values: )([a-z,]+)/i", $str, $match);
$values = explode(",", $match[2]);
foreach($values AS $value){
if(!$arr[$value]) $arr[$value] = true;
}
$return = $match[1];
foreach($arr AS $a){
$return .= ($i++ >= 1 ? "," : "").$a;
}

unique array values

I have string of comma separated values.
1,2,3,4,4,4,4,4,4,4,4,01633,4,4
I need to remove the duplicates, so I though of using
array_unique($str);
However, it returns no results. So I decided to output it to see what I have:
print_r($str);
// returns: 1,2,3,4,4,4,4,4,4,4,4,01633,4,4
I'm a little lost. I checked if it is an array and I got true. Here's how that string is created:
$str = '1,2,3';
foreach ($a as $b) {
$str.= ','.$b;
}
What am I missing here?
$str = explode(',', $str); // create array
$newArray = array_unique($str); // then process
actually, though... just do your array_unique() on $a before the string is created.
$a = array_unique($a);
then...
foreach ($a as $b) { // and so on
Convert to an array, remove the repeat values, convert to string
$str = 'whatever';
$arr = explode( ',', $str );
$newArr = array_unique( $arr );
$newStr = implode( ',', $newArr );
Explode on comma, make unique, glue pieces back together:
$str = implode(',', array_unique(explode(',', $str)));

array_map with str_replace

Is it possible to use array_map in conjunction with str_replace without calling another function to do the str_replace?
For example:
array_map(str_replace(' ', '-', XXXXX), $myArr);
There is no need for array_map. From the docs: "If subject is an array, then the search and replace is performed with every entry of subject, and the return value is an array as well."
No, it's not possible. Though, if you are using PHP 5.3, you can do something like this:
$data = array('foo bar baz');
$data = array_map(function($value) { return str_replace('bar', 'xxx', $value); }, $data);
print_r($data);
Output:
Array
(
[0] => foo xxx baz
)
Sure it's possible, you just have to give array_map() the correct input for the callback function.
array_map(
'str_replace', // callback function (str_replace)
array_fill(0, $num, ' '), // first argument ($search)
array_fill(0, $num, '-'), // second argument ($replace)
$myArr // third argument ($subject)
);
But for the particular example in the question, as chiborg said, there is no need. str_replace() will happily work on an array of strings.
str_replace(' ', '-', $myArr);
Might be important to note that if the array being used in str_replace is multi-dimensional, str_replace won't work.
Though this doesn't directly answer the question of using array_map w/out calling an extra function, this function may still be useful in place of str_replace in array_map's first parameter if deciding that you need to use array_map and string replacement on multi-dimensional arrays. It behaves the same as using str_replace:
function md_str_replace($find, $replace, $array) {
/* Same result as using str_replace on an array, but does so recursively for multi-dimensional arrays */
if (!is_array($array)) {
/* Used ireplace so that searches can be case insensitive */
return str_ireplace($find, $replace, $array);
}
$newArray = array();
foreach ($array as $key => $value) {
$newArray[$key] = md_str_replace($find, $replace, $value);
}
return $newArray;
}

PHP: Split string into 2D array

I have a string which contains quite a bit of data. I want to split the data into a 2D array. The data in the string is split by a ~ (tilde) for the columns and a : (colon) for the different rows.
An example string could be: "London~10~20~cold:New York~23~53~hot:Madrid~43~12~dry".
Thanks.
$string = "London~10~20~cold:New York~23~53~hot:Madrid~43~12~dry";
$array = explode(':', $string);
foreach($array as &$value) $value = explode('~', $value);
Functional way (PHP 5.3.x needed):
$string = "London~10~20~cold:New York~23~53~hot:Madrid~43~12~dry";
$map = array_map(function($el) {
return explode('~', $el);
}, explode(':', $string));
Another alternative would be:
preg_match_all('/(.*?)~(.*?)~(.*?)~(.*?)(?:$|:)/', $string, $array,
PREG_SET_ORDER);
It's more cumbersome in that you have to predefine the column format. It also returns the complete match in each rows [0]. Otherwise (due to PREG_SET_ORDER) it's in your desired 2d format.
Just posting it here to please and annoy the microoptimizers at the same time. Despite the common Stackoverflow meme, the regex is three times faster than the explode loop.
You can split data in php with explode().
So first you have to split the string, than you have to split your entries again with explode().
$data = explode(':', $string);
$array = array();
foreach($data as $d) {
$d = explode('~', $d);
$array[] = $d; //e.g. $array[0][0] --> London
//$array[$d[0]] = array('temperature' => $d[1], 'dont-know' => $d[2], 'climate' => $d[3]); //e.g. $arra['London'] => array(...)
}
A "functional" style
$array = array_map(function($value) {
return explode('~', $value);
}, explode(':',$string););

explode two-item-list in array as key=>value

I'd like to explode a multi-line-string like this
color:red
material:metal
to an array like this
$array['color']=red
$array['material']=metal
any idea?
Use explode(), you can use a regexp for it, but it's simple enough without the overhead.
$data = array();
foreach (explode("\n", $dataString) as $cLine) {
list ($cKey, $cValue) = explode(':', $cLine, 2);
$data[$cKey] = $cValue;
}
As mentioned in comments, if data is coming from a Windows/DOS environment it may well have CRLF newlines, adding the following line before the foreach() would resolve that.
$dataString = str_replace("\r", "", $dataString); // remove possible \r characters
The alternative with regexp can be quite pleasant using preg_match_all() and array_combine():
$matches = array();
preg_match_all('/^(.+?):(.+)$/m', $dataString, $matches);
$data = array_combine($matches[1], $matches[2]);
Try this
$value = '1|a,2|b,3|c,4|d';
$temp = explode (',',$value);
foreach ($temp as $pair)
{
list ($k,$v) = explode ('|',$pair);
$pairs[$k] = $v;
}
print_r($pairs);
explode first on line break. Prolly \n
Then explode each of the resulting array's items on : and set a new array to that key/value.

Categories