Jump to content

preg_match_all problem


iscode

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));

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));

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));
?>

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']);
   }
}
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']);
}

Archived

This topic is now archived and is closed to further replies.

×
×
  • 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.