Jump to content

preg_match_all problem


Go to solution Solved by Ch0cu3r,

Recommended Posts


I have the following string :
't':new Date(2014,1-1,3,9,35,38),'a':'3.57289','lat':'12,123','lon':'-12,123','dep':'1,1','s':'1,0','q':'90,02','dL':'4,3','dD':'VSV','dR':'PlaceName'

t=date and time
a=?
lat=latitude
lon=longitude
dep=depth
s=magnitude
q=quality
dL=?
dD=direction
dR=PlaceName

I am trying to get the data into array with preg_match_all
Can anyone help me out?


 

Link to comment
https://forums.phpfreaks.com/topic/285059-preg_match_all-problem/
Share on other sites

You could simplify it with explode

$string = "'t':new Date(2014,1-1,3,9,35,38),'a':'3.57289','lat':'12,123','lon':'-12,123','dep':'1,1','s':'1,0','q':'90,02','dL':'4,3','dD':'VSV','dR':'PlaceName'";

// explode on ,'
$data = explode(',\'', $string);

foreach($data as $key => $value)
{
    // remove current key/value from array
    unset($data[$key]);

    // get the key value pair
    list($key, $value) = explode(':', $value);

    // trim quotes
    $key   = trim($key, "'");
    $value = trim($value, "'");

    // assign key/value to array
    $data[$key] = $value;
}

printf('<pre>%s</pre>', print_r($data, true));
Edited by Ch0cu3r

After playing with regex I came up with this

$string = "'t':new Date(2014,1-1,3,9,35,38),'a':'3.57289','lat':'12,123','lon':'-12,123','dep':'1,1','s':'1,0','q':'90,02','dL':'4,3','dD':'VSV','dR':'PlaceName'";

// regex for finding keys
$keyMatch = "#'(\w+)':#";
// match all keys
preg_match_all($keyMatch, $string, $keys);

// split string on keys
$values = preg_split($keyMatch, $string);
$values = array_filter($values);
$values = array_map(function($value) {
                        return trim($value, "',");
                    }, $values);

// combine both arrays into key - value pairs
$data = array_combine($keys[1], $values);

printf('<pre>%s</pre>', print_r($data, true));

Thank you

 

but what if the $string is an array and I have to go through many $string?

 

So is this not a string but an array?

't':new Date(2014,1-1,3,9,35,38),'a':'3.57289','lat':'12,123','lon':'-12,123','dep':'1,1','s':'1,0','q':'90,02','dL':'4,3','dD':'VSV','dR':'PlaceName'

Sorry if I confuse you but what I mean is the $string is array like below

 

Array
(
    [0] => Array
        (
            [0] => {'t':new Date(2014,1-1,3,14,53,28),'a':'2.10978','lat':'12,123','lon':'-12,123','dep':'0,6','s':'0,0','q':'37,96','dL':'6,9','dD':'ANA ','dR':'PlaceName'}
            [1] => {'t':new Date(2014,1-1,3,9,35,38),'a':'7.40706','lat':'12,123','lon':'-12,123','dep':'1,1','s':'1,0','q':'90,02','dL':'4,3','dD':'VSV','dR':'PlaceName'}
        )

    [1] => Array
        (
            [0] => 't':new Date(2014,1-1,3,14,53,28),'a':'2.10978','lat':'12,123','lon':'-12,123','dep':'0,6','s':'0,0','q':'37,96','dL':'6,9','dD':'ANA ','dR':'PlaceName'
            [1] => 't':new Date(2014,1-1,3,9,35,38),'a':'7.40706','lat':'12,123','lon':'-12,123','dep':'1,1','s':'1,0','q':'90,02','dL':'4,3','dD':'VSV','dR':'PlaceName'
        )

)

Yes you'll need to loop over the array.

$data = array();
foreach($data_array[1] as $string)
{
    // regex for finding keys
    $keyMatch = "#'(\w+)':#";
    // match all keys
    preg_match_all($keyMatch, $string, $keys);

    // split string on keys
    $values = preg_split($keyMatch, $string);
    $values = array_filter($values);
    $values = array_map(function($value) {
                            return trim($value, "',");
                        }, $values);

    printf('<pre>%s</pre>', print_r([$keys, $values], true));

    // combine both arrays into key - value pairs
    $data[] = array_combine($keys[1], $values);

   unset($keys, $values);
}

printf('<pre>%s</pre>', print_r($data, true));
Edited by Ch0cu3r

It wont work for some reason maybe its my preg_match_all patterns.

Can you maybe see what I am doing wrong?

<?php 
$html = file_get_contents('http://www.vedur.is/skjalftar-og-eldgos/jardskjalftar');
preg_match_all('@VI.quakeInfo =(.*?)</script>@si', $html, $m);
preg_match_all('@{(.*?)}@si', $m[1][0], $data_array);

$data = array();
foreach ($data_array[1] as $string)
{
    // regex for finding keys
    $keyMatch = "#'(\w+)':#";
    // match all keys
    preg_match_all($keyMatch, $string, $keys);

// split string on keys
    $values = preg_split($keyMatch, $string);
    $values = array_filter($values);
    $values = array_map(function($value) {
                            return trim($value, "',");
                        }, $values);

    printf('<pre>%s</pre>', print_r([$keys, $values], true));

// combine both arrays into key - value pairs
    $data = array_combine($keys[1], $values);

   unset($keys, $values);
}

printf('<pre>%s</pre>', print_r($data, true));
?>

  • Solution

Ohh, you're dealing with JSON.

 

Code simplified futher

preg_match_all('~VI.quakeInfo = \[([^\]]+)\]~', $data, $matches);
preg_match_all('~\{[^}]+\}~', $matches[1][0], $data_array);

$quakeInfo = array();
foreach ($data_array[0] as $string)
{
    // convert javascript json to be compatible with PHP
    $string = preg_replace('~:(new Date\([^)]+\))~', ':"$1"', str_replace("'", '"', $string));

    // decode the json
    $json = json_decode($string, true);

    // group data into reigons (dR)
    $quakeInfo[ $json['dR'] ][] = $json;
}

printf('<pre>%s</pre>', print_r($quakeInfo, true));

Change

// convert javascript json to be compatible with PHP
    $string = preg_replace('~:(new Date\([^)]+\))~', ':"$1"', str_replace("'", '"', $string));

to

// convert javascript json to be compatible with PHP
    $string = str_replace("'", '"', $string);

    // convert the date into a timestamp
    $string = preg_replace_callback('~new Date\(([^)]+)\)~', function($dateParams) {
                                                                    // get the date parameters
                                                                    list($year, $month, $day, $hour, $min, $sec) = explode(',', $dateParams[1]);

                                                                    // remove the javascript math operation for the month
                                                                    $month = substr($month, 0, strpos($month, '-'));

                                                                    // create the timestamp
                                                                    return mktime($hour, $min, $sec, $month, $day, $year);
                                                              }, $string);

When you goto display the date later on you can convert the timestamp to english readable format (eg January 3, 2014, 11:37 pm) using date, eg

foreach($quakeInfo as $region => $regionData)
{
   echo "<h1>$region</h1>";
   foreach($regionData as $quake)
   {
      // convert timestamp to english readable format
      echo date('F j, Y, g:i a', $quake['t']);
   }
}
Edited by Ch0cu3r
foreach($quakeInfo as $region => $regionData)
{
   echo "<h1>$region</h1>";
   foreach($regionData as $quake)
   {
      // convert timestamp to english readable format
      echo date('F j, Y, g:i a', $quake['t']);
   }
}

The abow code display the data as group, how would it be coded without group each data? 

Change

// group data into reigons (dR)
$quakeInfo[ $json['dR'] ][] = $json;

to

// add quake data to array
$quakeInfo[] = $json;

Then use a single foreach loop to output your data

foreach($quakeInfo as $quake)
{
   // convert timestamp to english readable format
   echo date('F j, Y, g:i a', $quake['t']);
}
Edited by Ch0cu3r
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.