Convert backslash-delimited string into an associative array
Using a simple regex via preg_match_all
and array_combine
is often the shortest and quickest option:
preg_match_all("/([^\\\\]+)\\\\([^\\\\]+)/", $string, $p);
$array = array_combine($p[1], $p[2]);
Now this is of course a special case. Both keys and values are separated by a \ backslash, as are all pairs of them. The regex is also a bit lengthier due to the necessary double escaping.
However this scheme can be generalized to other key:value,
-style strings.
Distinct key:value,
separators
Common variations include : and = as key/value separators, and , or & and others as pair delimiters. The regex becomes rather obvious in such cases (with the /x
flag for readability):
# ↓ ↓ ↓
preg_match_all("/ ([^:]+) : ([^,]+) /x", $string, $p);
$array = array_combine($p[1], $p[2]);
Which makes it super easy to exchange :
and ,
for other delimiters.
- Equal signs
=
instead of:
colons. - For example
\\t
as pair delimiter (tab-separated key:value lists) - Classic
&
or;
as separator between key=value pairs. - Or just
\\s
spaces or\\n
newlines even.
Allow varying delimiters
You can make it more flexible/forgiving by allowing different delimiters between keys/values/pairs:
# ↓ ↓ ↓
preg_match_all("/ ([^:=]+) [:=]+ ([^,+&]+) /x", $string, $p);
Where both key=value,key2:value2++key3==value3
would work. Which can make sense for more human-friendlinies (AKA non-technical users).
Constrain alphanumeric keys
Oftentimes you may want to prohibit anything but classic key
identifiers. Just use a \w+
word string pattern to make the regex skip over unwanted occurences:
# ↓ ↓ ↓
preg_match_all("/ (\w+) = ([^,]+) /x", $string, $p);
This is the most trivial whitelisting approach. If OTOH you want to assert/constrain the whole key/value string beforehand, then craft a separate preg_match("/^(\w+=[^,]+(,|$))+/", …
Strip spaces or quoting
You can skip a few post-processing steps (such as trim
on keys and values) with a small addition:
preg_match_all("/ \s*([^=]+) \s*=\s* ([^,]+) (?<!\s) /x", $string, $p);
Or for instance optional quotes:
preg_match_all("/ \s*([^=]+) \s*=\s* '? ([^,]+) (?<![\s']) /x", $string, $p);
INI-style extraction
And you can craft a baseline INI-file extraction method:
preg_match_all("/^ \s*(\w+) \s*=\s* ['\"]?(.+?)['\"]? \s* $/xm", $string, $p);
Please note that this is just a crude subset of common INI schemes.
Alternative: parse_str()
If you have a key=value&key2=value2
string already, then parse_str
works like a charm. But by combining it with strtr
can even process varying other delimiters:
# ↓↓ ↑↑
parse_str(strtr($string, ":,", "=&"), $pairs);
Which has a couple of pros and cons of its own:
- Even shorter than the two-line regex approach.
- Predefines a well-known escaping mechanism, such as
%2F
for special characters). - Does not permit varying delimiters, or unescaped delimiters within.
- Automatically converts
keys[]=
to arrays, which you may or may not want though.
Alternative: explode
+ foreach
You'll find many examples of manual key/value string expansion. Though this is often more code. explode
is somewhat overused in PHP due to optimization assumptions. After profiling often turns out to be slower however due to the manual foreach
and array collection.
How can I convert an array of strings into an associative array in PHP?
As simple as:
$arr = array(
"action: Added; amount: 1; code: RNA1; name: Mens Organic T-shirt; colour: White; size: XL",
"action: Subtracted; amount: 7; code: RNC1; name: Kids Basic T-shirt; colour: Denim Blue; size: 3-4y",
"action: Added; amount: 20; code: RNV1; name: Gift Voucher; style: Mens; value: £20",
);
$data = [];
foreach ($arr as $line) {
$newItem = [];
foreach (explode(';', $line) as $item) {
$parts = explode(':', $item);
$newItem[trim($parts[0])] = trim($parts[1]);
}
$data[] = $newItem;
}
print_r($data);
Fiddle here.
Split string with only one delimiting character into key-value pairs
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>";
explode array into associative array which already exploded in php
This should do:
<?php
$info = "SportId : 56,GroundType : Public,SelectArea : 10,Cost : 3000-4000 ,Size : 7 * 7";
$arrInfo = explode(",",$info);
$newArray = [];
foreach($arrInfo as $item) {
$values = explode(":",$item);
$newArray[$values[0]] = $values[1];
}
print_r($newArray);
Explode a string to associative array without using loops?
Here's a way to do it without a for loop, using array_walk:
$array = explode(',', $string);
$new_array = array();
array_walk($array,'walk', $new_array);
function walk($val, $key, &$new_array){
$nums = explode('-',$val);
$new_array[$nums[0]] = $nums[1];
}
Example on Ideone.com.
Turning String Into Array
$str = 'twitter:3 facebookshare_count:5 like_count:0 comment_count:0 total_count:8 click_count:5 buffer:0 pinterest:0 linkedin:0 stumbleupon:0 redditscore:0 ups:8 downs:3 google:4 delicious:0 digg:0';
$strArray = explode(' ', $str);
$desiredArray = [];
foreach ($strArray as $value) {
$value = explode(":", $value);
$desiredArray[$value[0]] = $value[1];
}
exploding string with multiple delimiter
Tokens all the way down...
<?php
$str = '1-a,2-b,3-c';
$token = '-,';
if($n = strtok($str, $token))
$array[$n] = strtok($token);
while($n = strtok($token))
$array[$n] = strtok($token);
var_export($array);
Output:
array (
1 => 'a',
2 => 'b',
3 => 'c',
)
Or perhaps more terse without the first if...:
$array = [];
while($n = $array ? strtok($token) : strtok($str, $token))
$array[$n] = strtok($token);
How to convert string to PHP array?
This should work as inteded, to solve this problem, you just need to use explode() correctly, otherwise it's easy.
Here you go :
$firstarr=explode('&',$yourstring);
$desiredarr=array();
foreach($firstarr as $pair)
{
$exp_pair=explode('=',$pair);
$desiredarr[$exp_pair[0]]=$exp_pair[1];
}
print_r($desiredarr);
Converting a string into a multi-dimensional array with commas and pipes
I wouldn't even bother with looking for |
or manually traversing anything. You can generate the desired array already with preg_match_all
containing just a few fillers:
preg_match_all(
"/(?<sku>\w+),(?<qty>\d+)\K/",
$string, $array, PREG_SET_ORDER
);
This simply extracts any combination of alphanumeric \w+
and numeric \d+
entries delimited by ,
comma.
Related Topics
PHP Multidimensional Array Searching (Find Key by Specific Value)
How to Query Between Two Dates Using Laravel and Eloquent
Speed Difference in Using Inline Strings VS Concatenation in PHP5
Difference Between PHP Echo and PHP Return in Plain English
How to Start and End Transaction in MySQLi
Json_Decode Returns Null After Webservice Call
Convert Command Line Curl to PHP Curl
How to Convert a Number to a Word in PHP
How to Loop Through Two Arrays At Once
Change Cart Item Prices in Woocommerce 3
Does PHP Allow Named Parameters So That Optional Arguments Can Be Omitted from Function Calls
Ajax and PHP to Enter Multiple Forms Input to Database
How to Handle the Warning of File_Get_Contents() Function in PHP
Getting Title and Meta Tags from External Website
Http Authentication Logout Via PHP