Search code examples
phpfile-get-contentspreg-match-all

PHP substr function does not parse properly in foreach


I have some files containing the similar formats as follows:

Nearest Location:
771 km S 43° E of Quezon City
051 km S 66° E of Surigao City 
007 km S 51° W of Socorro (Surigao Del Norte)
049 km N 70° E of PFZ EAST MINDANAO SEGMENT

What I did was to load each file through file_get_contents() and explode("\n",...). So I used foreach($rows_location as $row_location) and stored it to $content_location = $row_location;. I separated it into 2 parts, the distance and bearing info, and the location neglecting the first line which is as follows:

$distance_bearing = substr($content_location,0,18);
$location = substr($content_location, 18);

but the problem is that it only works for the first row so i saved them separately and got

771 km S 43° E of

for $distance_bearing and

Quezon City
051 km S 66° E of Surigao City 
007 km S 51° W of Socorro (Surigao Del Norte)
049 km N 70° E of PFZ EAST MINDANAO SEGMENT

for $location.

I tried converting each row to utf8_decode as it contains a degree symbol and it just returned the same but with the degree replaced with ?. I also checked $content_location if it stores the rows properly and got:

Nearest Location:
771 km S 43° E of Quezon City
051 km S 66° E of Surigao City 
007 km S 51° W of Socorro (Surigao Del Norte)
049 km N 70° E of PFZ EAST MINDANAO SEGMENT

so I guess it stores it correctly.

I don't know what the problem is, so any ideas will help. Thank you in advance for the help.


Sorry guys, I forgot to put the desired output it should be:

771 km S 43° E of
051 km S 66° E of
007 km S 51° W of
049 km N 70° E of

for $distance_bearing and

Quezon City
Surigao City 
Socorro (Surigao Del Norte)
PFZ EAST MINDANAO SEGMENT

for $location. Thanks again!


Solution

  • preg_match_all() will handle the block of text simply.

    Code: (Demo)

    $string='Nearest Location:
    771 km S 43° E of Quezon City
    051 km S 66° E of Surigao City
    007 km S 51° W of Socorro (Surigao Del Norte)
    049 km N 70° E of PFZ EAST MINDANAO SEGMENT';
    
    if(preg_match_all('/^(.*? of) \K.+/m',$string,$out)){
        list($location,$distance_bearing)=$out;
    }
    var_export($distance_bearing);
    echo "\n\n";
    var_export($location);
    

    Output:

    array (
      0 => '771 km S 43° E of',
      1 => '051 km S 66° E of',
      2 => '007 km S 51° W of',
      3 => '049 km N 70° E of',
    )
    
    array (
      0 => 'Quezon City',
      1 => 'Surigao City',
      2 => 'Socorro (Surigao Del Norte)',
      3 => 'PFZ EAST MINDANAO SEGMENT',
    )
    

    Pattern Explanation:

    /         # start the pattern
    ^         # match from the start of the line
    (.*? of)  # match the leading text upto and including the first occurrence of `of`
     \K.+     # match 1 space, then restart the fullstring match using \K then match the rest of the string
    /         # end the pattern
    m         # force ^ character to match every line start instead of string start