Convert string with two delimiters into flat associative array [duplicate]
Asked Answered
I

4

2

I'm really have no idea about regex... So I got stuck... Can anyone give me a solution with explanation of regex itself?

Here is my code:

$str = "id:521082299088|name:JOHNSON GREIG DENOIA|mounth:JAN17|amount:170027|admin:2500|billqty:1|metre:R1/900|usage:00010261-00010550|reffno:0BKP21851AF3EC2E0D4F56997EA19DFA|charge:170377|balace:1935";
$pregsplit = preg_split("/[\s|]+/",$string2);

Output:

Array
(
    [0] => id:521082299088
    [1] => name:JOHNSON
    [2] => GREIG
    [3] => DENOIA
    [4] => mounth:JAN17
    [5] => amount:170027
    [6] => admin:2500
    [7] => billqty:1
    [8] => metre:R1/900
    [9] => usage:00010261-00010550
    [10] => reffno:0BKP21851AF3EC2E0D4F56997EA19DFA
    [11] => charge:170377
    [12] => balance:1935
)

I want output like this:

Array
(
    "id" => 521082299088
    "name" => "JOHNSON GREIG DENOIA"
    "mount" => "JAN17"
    "amount" => 170027
    "admin" => 2500
    "billqty" => 1
    "metre" => "R1/900"
    "usage" => "00010261-00010550"
    "reffno" => "0BKP21851AF3EC2E0D4F56997EA19DFA"
    "charge" => 170377
    "balance" => 1935
)
Iapetus answered 28/1, 2017 at 16:57 Comment(0)
H
4

1) The solution using preg_match_all function with specific regex pattern:

$str = "id:521082299088|name:JOHNSON GREIG DENOIA|mounth:JAN17|amount:170027|admin:2500|billqty:1|metre:R1/900|usage:00010261-00010550|reffno:0BKP21851AF3EC2E0D4F56997EA19DFA|charge:170377|balace:1935";

preg_match_all("/(\w+):([^|]+)/", $str, $matches, PREG_SET_ORDER);
$result = [];
foreach ($matches as $items) {
    $result[$items[1]] = $items[2];
}
// $items[1] contains a "parameter" name captured by the first capturing group (\w+)
// $items[2] contains a "parameter" value captured by the second capturing group ([^|]+)

print_r($result);

The output:

Array
(
    [id] => 521082299088
    [name] => JOHNSON GREIG DENOIA
    [mounth] => JAN17
    [amount] => 170027
    [admin] => 2500
    [billqty] => 1
    [metre] => R1/900
    [usage] => 00010261-00010550
    [reffno] => 0BKP21851AF3EC2E0D4F56997EA19DFA
    [charge] => 170377
    [balace] => 1935
)

(\w+) - matches all alphanumeric characters followed by :

([^|]+) - matches all characters excepting | which is delimiter

http://php.net/manual/en/function.preg-match-all.php


2) In addition to the first approach - using array_combine function(to combine all respective values from two capturing groups):

preg_match_all("/(\w+):([^|]+)/", $str, $matches);
$result = array_combine($matches[1], $matches[2]);
// will give the same result

3) The third alternative approach would be using explode() function:

$result = [];
foreach (explode("|", $str) as $items) {
    $pair = explode(":", $items);
    $result[$pair[0]] = $pair[1];
}
Holophytic answered 28/1, 2017 at 17:4 Comment(9)
Can you explain to me that regex ? for each charactersIapetus
@KurniawanNanda, added explanationHolophytic
It seems the positive lookahead isn't necessary in your expression.Obidiah
@KurniawanNanda I would recommend you to search for online live regex editing tools to practice it. Those would help to understand regexes better. I would really recommend regexr.com for example.Thermel
@Niitaku, ok, removedHolophytic
@Kurniawan Nanda you can just use explode() method.If you are new in regular expression.Counselor
@Holophytic Thanksssssssssssssssss I really appreciate thatIapetus
If you remove PREG_SET_ORDER, you can build the result using array_combine without a loop.Unpriced
@CasimiretHippolyte, ok, added as an alternativeHolophytic
C
2

If you are unable to write regular expression.Here is a simple solution using explode() method.The explode() function breaks a string into an array.

<?php
$str = "id:521082299088|name:JOHNSON GREIG DENOIA|mounth:JAN17|amount:170027|admin:2500|billqty:1|metre:R1/900|usage:00010261-00010550|reffno:0BKP21851AF3EC2E0D4F56997EA19DFA|charge:170377|balace:1935";

$array = explode('|',$str);
foreach($array as $key=>$value){
 $data = explode(':',$value);
 $final[$data[0]] = $data[1];

}
print_r($final);

?>

Output:

Array
(
    [id] => 521082299088
    [name] => JOHNSON GREIG DENOIA
    [mounth] => JAN17
    [amount] => 170027
    [admin] => 2500
    [billqty] => 1
    [metre] => R1/900
    [usage] => 00010261-00010550
    [reffno] => 0BKP21851AF3EC2E0D4F56997EA19DFA
    [charge] => 170377
    [balace] => 1935
)

To learn more about explode() read docs http://php.net/manual/en/function.explode.php

Counselor answered 28/1, 2017 at 17:15 Comment(0)
U
1

A funny way (only if your string doesn't contain = or &): translate pipes to ampersands and colons to equal signs, then parse it as an URL query with parse_str:

$str = "id:521082299088|name:JOHNSON GREIG DENOIA|mounth:JAN17|amount:170027|admin:2500|billqty:1|metre:R1/900|usage:00010261-00010550|reffno:0BKP21851AF3EC2E0D4F56997EA19DFA|charge:170377|balace:1935";

parse_str(strtr($str, ':|', '=&'), $result);

print_r($result);

demo

Unpriced answered 28/1, 2017 at 17:54 Comment(0)
E
0

This approach would be an alternative.

You can separate string and create an array from it using PHP's explode() function. Then you can separate the 'key:value' structure using strpos() and substr() functions.

// input string
$str = "id:521082299088|name:JOHNSON GREIG DENOIA|mounth:JAN17|amount:170027|admin:2500|billqty:1|metre:R1/900|usage:00010261-00010550|reffno:0BKP21851AF3EC2E0D4F56997EA19DFA|charge:170377|balace:1935";

// make an array out of the string, split elements on each pipe character ('|')
$arr = explode('|', $str);

// create an output array to keep the results
$output = [];

// process the array
foreach ($arr as $item) {
    // get delimiter
    $separatorPos = strpos($item, ':');
    // take the key part (The part before the ':')
    $key = substr($item, 0, $separatorPos);
    // take the value part (The part after the ':')
    $value = substr($item, $separatorPos);
    // push it into the output array
    $output[$key] = $value;
}

// dump the output array
var_export($output);

Dump of the output array would be like follwing;

[
    'id'      => ':521082299088',
    'name'    => ':JOHNSON GREIG DENOIA',
    'mounth'  => ':JAN17',
    'amount'  => ':170027',
    'admin'   => ':2500',
    'billqty' => ':1',
    'metre'   => ':R1/900',
    'usage'   => ':00010261-00010550',
    'reffno'  => ':0BKP21851AF3EC2E0D4F56997EA19DFA',
    'charge'  => ':170377',
    'balace'  => ':1935',
]
Es answered 28/1, 2017 at 17:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.