-1

I've the following string:

$html = '"id":75549,"name":"Name","lat":"45.491834","lng":" -73.606953","address"';

I would like to extract the lat and lng datas.

This is my try:

$lat = preg_match_all('#lat":"(.*?)","lng#', $html, $matches);
$lat = matches[1];

But it doesn't work.

Could you please help me please ?

Thanks.

popol
  • 213
  • 1
  • 9
  • 3
    ...this looks like a JSON string. Why do you need regex for this? – Dharman Jun 15 '19 at 15:43
  • 3
    Partial/truncated JSON string. If it's possible to keep the full structure, with `{}`, then parsing that would be ideal as Dharman says. Also, the question title reminds me strongly of the example in [this meta post on the xy problem](https://meta.stackexchange.com/a/66378/399876). – ggorlen Jun 15 '19 at 15:45
  • @Dharman, my `$html`, is only a light version of the result of a `file_get_contents()`. – popol Jun 15 '19 at 15:47
  • What file are you reading in? What is inside the file? How did you get just a malformed part of that file in your variable? – Dharman Jun 15 '19 at 15:49
  • If the full content is a JSON resource then - https://stackoverflow.com/questions/29308898/how-do-i-extract-data-from-json-with-php or for a file - https://stackoverflow.com/questions/4343596/how-can-i-parse-a-json-file-with-php – Nigel Ren Jun 15 '19 at 15:51

3 Answers3

3

json_decode is much more reliable than regex. Add braces and a value for the missing "address" element and you can index directly into the result:

<?php
$html = '"id":75549,"name":"Name","lat":"45.491834","lng":" -73.606953","address"';

$decoded = json_decode('{'.$html.':""}', true);

echo "lat: ".$decoded["lat"]."  lng: ".$decoded["lng"];

Output:

lat: 45.491834  lng:  -73.606953
ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • 1
    Why creating a new property `root` during decoding and then accessing it ? whereas you can directly decode ? – Code Maniac Jun 15 '19 at 15:53
  • Thanks for your help. It works but as I explain in the comments, my `$html`, is only a light version of the result of a `file_get_contents()`. – popol Jun 15 '19 at 16:03
2

This expression would likely extract our desired latitude and longitude data in this capturing group (.+?), as it also removes the undesired spaces:

("lat":|"lng":)"\s*(.+?)\s*"

Test

$re = '/("lat":|"lng":)"\s*(.+?)\s*"/m';
$str = '"id":75549,"name":"Name","lat":"45.491834","lng":" -73.606953","address"';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

var_dump($matches[0][2]);
var_dump($matches[1][2]);


foreach ($matches as $key => $value) {
    echo $value[2] . "\n";
}

Output

45.491834
-73.606953

Demo

Emma
  • 27,428
  • 11
  • 44
  • 69
  • 1
    Hello, thanks for your help. And if I only need only the `$lat` do I need to use the `foreach` ? – popol Jun 15 '19 at 16:03
  • 1
    If you only need one and you have to use regex, use `preg_match` and remove `"lng"` alternation from the regex pattern. – ggorlen Jun 15 '19 at 16:06
2

"lat":"\s*([^"]*?\s*"),"lng":"\s*([^"]*?\s*)"\K

Values in group 1 and group 2

https://regex101.com/r/jDWL84/1

Php Code

Sandbox Demo

 <?php

 $str = '
 "id":75549,"name":"Name","lat":"45.491834","lng":" -73.606953","address"
 "id":75550,"name":"Name","lat":"44.491834","lng":" -72.606953","address"
 "id":75551,"name":"Name","lat":"43.491834","lng":" -71.606953","address"
 ';

 $cnt = preg_match_all('/"lat":"\s*([^"]*?\s*)","lng":"\s*([^"]*?\s*)"\K/', $str, $latlng, PREG_SET_ORDER );

 if ( $cnt > 0 )
 {
     // print_r ( $latlng );
     for ( $i = 0; $i < $cnt; $i++ )
     {
         echo "( lat, long ) = ( " . $latlng[$i][1] . ", " . $latlng[$i][2] . " )\n";
     }
 }

 >

Output

( lat, long ) = ( 45.491834, -73.606953 )
( lat, long ) = ( 44.491834, -72.606953 )
( lat, long ) = ( 43.491834, -71.606953 )
  • Shloud I integrate it like this: `preg_match_all('"lat":"\s*([^"]*?\s*"),"lng":"\s*([^"]*?\s*)"\K', $html, $latlng); echo 'Lat is '.$latlng[0];` ? – popol Jun 15 '19 at 15:59
  • @popo - You're matching a pair, a coordinate. Do it however you want. `[[lat,long],[lat,long],,,]` –  Jun 15 '19 at 16:03
  • So like this: `echo $latlng[lat,long]` ? – popol Jun 15 '19 at 16:06
  • @popol - Yeah, like `echo "( lat, long ) = ( " . $latlng[$i][1] . ", " . $latlng[$i][2] . " )\n";` –  Jun 15 '19 at 16:47
  • @popol - Just a warning for ya. If you don't match in pairs, you will miss one (that's not an if) and you will not have viable coordinates. –  Jun 15 '19 at 16:50