Jobin
Jobin

Reputation: 8282

How to parse the string to array

I have following value in a table column is there any option to get the sandbox value and merchant_email like array ? I know using explode and loop is works but any other smart options ? something like $result->sandbox

 paypal_merchant_email="[email protected]"|paypal_verified_only="0"|payment_currency=""|sandbox="1"|sandbox_merchant_email="[email protected]"|payment_logos=""|debug="0"|status_pending="W"|status_success="O"|status_canceled="D"|countries=""|min_amount="0"|max_amount="0"|secure_post=""|ipn_test=""|no_shipping="0"|address_override="0"|cost_per_transaction="0"|cost_percent_total="0"|tax_id=0|

Thanks in advance!

Upvotes: 1

Views: 212

Answers (6)

Marina
Marina

Reputation: 491

Here is the very compact solution for you:

preg_match_all('/\|(.*?)="(.*?)"/', '|'.$string, $matches);
$result = array_combine($matches[1], $matches[2]);

Test it here: https://3v4l.org/rfBuc

Upvotes: 0

Prix
Prix

Reputation: 19528

Little benchmark magic:

<?php
// explode
$start = microtime(TRUE);
$data = array();
foreach (explode('|', $result->sandbox) as $item)
{
    if (empty($item)) continue;
    list($key, $value) = explode("=", $item);
    $data[$key] = str_replace('"', '', $value);
}
print_r($data);
$stop = microtime(TRUE);
$timeResult = $stop - $start;
echo $timeResult, "\n";

//preg_split
$start = microtime(TRUE);
$data = array();
foreach (preg_split('/\|/', $result->sandbox) as $item)
{
    if (empty($item)) continue;
    list($key, $value) = preg_split('/=/', $item);
    $data[$key] = str_replace('"', '', $value);
}
print_r($data);
$stop = microtime(TRUE);
$timeResult = $stop - $start;
echo $timeResult, "\n";

//preg_match_all
$start = microtime(TRUE);
$data = array();
preg_match_all('/([^=]+)="([^"]+)?"\|/', $result->sandbox, $result);
$data = array_combine($result[1], $result[2]);
print_r($data);
$stop = microtime(TRUE);
$timeResult = $stop - $start;
echo $timeResult, "\n";

Result:

Array
(
    [paypal_merchant_email] => [email protected]
    [paypal_verified_only] => 0
    [payment_currency] =>
    [sandbox] => 1
    [sandbox_merchant_email] => [email protected]
    [payment_logos] =>
    [debug] => 0
    [status_pending] => W
    [status_success] => O
    [status_canceled] => D
    [countries] =>
    [min_amount] => 0
    [max_amount] => 0
    [secure_post] =>
    [ipn_test] =>
    [no_shipping] => 0
    [address_override] => 0
    [cost_per_transaction] => 0
    [cost_percent_total] => 0
    [tax_id] => 0
)
0.00029397010803223

Array
(
    [paypal_merchant_email] => [email protected]
    [paypal_verified_only] => 0
    [payment_currency] =>
    [sandbox] => 1
    [sandbox_merchant_email] => [email protected]
    [payment_logos] =>
    [debug] => 0
    [status_pending] => W
    [status_success] => O
    [status_canceled] => D
    [countries] =>
    [min_amount] => 0
    [max_amount] => 0
    [secure_post] =>
    [ipn_test] =>
    [no_shipping] => 0
    [address_override] => 0
    [cost_per_transaction] => 0
    [cost_percent_total] => 0
    [tax_id] => 0
)
0.00031495094299316

Another:

Array
(
    [paypal_merchant_email] => [email protected]
    [paypal_verified_only] => 0
    [payment_currency] =>
    [sandbox] => 1
    [sandbox_merchant_email] => [email protected]
    [payment_logos] =>
    [debug] => 0
    [status_pending] => W
    [status_success] => O
    [status_canceled] => D
    [countries] =>
    [min_amount] => 0
    [max_amount] => 0
    [secure_post] =>
    [ipn_test] =>
    [no_shipping] => 0
    [address_override] => 0
    [cost_per_transaction] => 0
    [cost_percent_total] => 0
    [tax_id] => 0
)
0.00026917457580566

Array
(
    [paypal_merchant_email] => [email protected]
    [paypal_verified_only] => 0
    [payment_currency] =>
    [sandbox] => 1
    [sandbox_merchant_email] => [email protected]
    [payment_logos] =>
    [debug] => 0
    [status_pending] => W
    [status_success] => O
    [status_canceled] => D
    [countries] =>
    [min_amount] => 0
    [max_amount] => 0
    [secure_post] =>
    [ipn_test] =>
    [no_shipping] => 0
    [address_override] => 0
    [cost_per_transaction] => 0
    [cost_percent_total] => 0
    [tax_id] => 0
)
0.00028419494628906

Upvotes: 1

pp19dd
pp19dd

Reputation: 3633

Here's possibly a more elegant solution using str_getcsv, array_walk, use, parse_str and the venerable each (to extract the key / value pairs). With your data:

$string = 'paypal_merchant_email="[email protected]"|paypal_verified_only="0"|payment_currency=""|sandbox="1"|sandbox_merchant_email="[email protected]"|payment_logos=""|debug="0"|status_pending="W"|status_success="O"|status_canceled="D"|countries=""|min_amount="0"|max_amount="0"|secure_post=""|ipn_test=""|no_shipping="0"|address_override="0"|cost_per_transaction="0"|cost_percent_total="0"|tax_id=0|';

Idea is to first use str_getcsv to parse the |-separated line, then traverse it using fast PHP functions.

$t = str_getcsv( $string, "|" );

At this point, $t is a simple array containing broken up "key=value" pairs.

$new = array();
array_walk( $t, function( &$a ) use (&$new) {
    parse_str( $a, $b);            # parses each line, returns key-value
    $c = each( $b );               # need to obtain key-value from above
    $new[$c["key"]] = $c["value"]; # simple assignment
});

This requires PHP > 5.3.0 since it uses namespaces (use) in the anonymous function. However, if you made it this far, print_r( $new ); gives you this:

Array (
    [paypal_merchant_email] => "[email protected]"
    [paypal_verified_only] => "0"
    [payment_currency] => ""
    ...

Upvotes: 0

Marina
Marina

Reputation: 491

If you need just one or two values, use regular expressions:

function get_value_from_string($key, $str) {
    return preg_match('/\|'.$key.'=([^\|]*)/', '|'.$str, $matches) ? eval("return $matches[1];") : null;
}

Upvotes: 0

Ryan
Ryan

Reputation: 14649

$string = 'paypal_merchant_email="[email protected]"|paypal_verified_only="0"|payment_currency=""|sandbox="1"|sandbox_merchant_email="[email protected]"|payment_logos=""|debug="0"|status_pending="W"|status_success="O"|status_canceled="D"|countries=""|min_amount="0"|max_amount="0"|secure_post=""|ipn_test=""|no_shipping="0"|address_override="0"|cost_per_transaction="0"|cost_percent_total="0"|tax_id=0|';

$result = array();
$string = preg_split('/\|/', $string);
foreach($string as $key => $value) 
{
    $value = str_replace('"', '', $value);
    $value = preg_split('/=/', $value);
    if(strlen($value[0])> 0) 
    {
       $result[$value[0]] = array_key_exists(1, $value) ? $value[1] : NULL;
    }
}

echo "<pre>";
print_r($result);
echo "</pre>";

Output

Array
(
    [paypal_merchant_email] => [email protected]
    [paypal_verified_only] => 0
    [payment_currency] => 
    [sandbox] => 1
    [sandbox_merchant_email] => [email protected]
    [payment_logos] => 
    [debug] => 0
    [status_pending] => W
    [status_success] => O
    [status_canceled] => D
    [countries] => 
    [min_amount] => 0
    [max_amount] => 0
    [secure_post] => 
    [ipn_test] => 
    [no_shipping] => 0
    [address_override] => 0
    [cost_per_transaction] => 0
    [cost_percent_total] => 0
    [tax_id] => 0
    [] => 
)

Upvotes: 1

Marina
Marina

Reputation: 491

There is a function parse_str() but it is for & delimiter: http://php.net/manual/en/function.parse-str.php

Or you can impress somebody with knowledge or PHP functions:

$str = 'a=13|b="string"|';

$rawarray = preg_split('/\|/', $str, -1, PREG_SPLIT_NO_EMPTY);
$keys = array_map(create_function('$a', '$r = preg_split("/=/", $a); return $r[0];'), $rawarray);
$values = array_map(create_function('$a', '$r = preg_split("/=/", $a, 2); return eval("return $r[1];");'), $rawarray);
$result = array_combine($keys, $values);

print_r($result);

Upvotes: 0

Related Questions