4

I am trying to parse a file using php but I am not sure of the best way to do it. The file consists of stuff like:

saturn+5 57 space+shuttle 34 gemini 12 mercury 2 soyuz+tm 1

What I'm trying to do is split it up and populate a hash map, so..

$inventory["saturn+5"] = "57";
$inventory["space+shuttle"] = "34";
and so on.

I don't know how to tackle this.

I am trying to write a bit of regex to process the file to separate out the fields but I'm not having much luck and was wondering if I should try using a different approach using split() or explode().

Nalaka526
  • 11,278
  • 21
  • 82
  • 116
user3713442
  • 478
  • 8
  • 22
  • 1
    Well, `explode` would be quite a cumbersome approach. What are you regex attempts? – mario Jun 06 '14 at 01:50
  • My first attempt was something like '/([.*]\s[0-9]*)/' but I don't think this would give me what I wanted. It would give me something like $splitstring[0]="saturn+5"; $splitstring[1]="57";$splitstring[2]="space+shuttle"; etc. So I'd have to loop through the array, so the odd numbered indices would be the key and the even indices the value, but this struck me as cumbersome. I thought there was a one-step approach that would do the odd/even index assignation immediately. – user3713442 Jun 06 '14 at 01:57

4 Answers4

2

my crude approach:

<?php
echo '<pre>';
$str="saturn+5 57 space+shuttle 34 gemini 12 mercury 2 soyuz+tm 1";

//break it on space
$e=explode(' ',$str);

//reindex array to start from 1
array_unshift($e, "phoney");
unset($e[0]);

print_r($e);
$inventory=array();
foreach ($e as $k=>$v){

//detects odd key   
if(($k+2)%2==1) {

$inventory[$v]= $e[$k+1];

    }

}

print_r($inventory);

demo: http://codepad.viper-7.com/PN6K8m

output:

Array
(
    [saturn+5] => 57
    [space+shuttle] => 34
    [gemini] => 12
    [mercury] => 2
    [soyuz+tm] => 1
)
2

If it's always in that order, this will work:

<?

$foo = 'saturn+5 57 space+shuttle 34 gemini 12 mercury 2 soyuz+tm 1';
$foo_array = preg_split('/\s+/', $foo);

$hash = array();
for ($i = 0; $i < count($foo_array); $i++){
    $i % 2 ? null : $hash[$foo_array[$i]] = $foo_array[++$i];
}

print_r($hash);
?>

Output:

php foo.php
Array
(
    [saturn+5] => 57
    [space+shuttle] => 34
    [gemini] => 12
    [mercury] => 2
    [soyuz+tm] => 1
)
fin
  • 333
  • 1
  • 4
2

Here's my approach using regular expression.

$data = 'saturn+5 57 space+shuttle 34 gemini 12 mercury 2 soyuz+tm 1';

$inventory = array();

preg_match_all('/(\S+) (\S+)/', $data, $matches);
foreach ($matches[1] as $index => $match) {
   $inventory[$match] = $matches[2][$index];
}
print_r($inventory);

Output

Array
(
    [saturn+5] => 57
    [space+shuttle] => 34
    [gemini] => 12
    [mercury] => 2
    [soyuz+tm] => 1
)
hwnd
  • 69,796
  • 4
  • 95
  • 132
  • There are some great solutions on this page, many thanks. I went for the option above as it was the first one I tried and it worked. – user3713442 Jun 06 '14 at 02:17
2

It's actually quite trivial with a regex:

preg_match_all("/  ([\w+]+)  \s  (\d+)  /x", $string, $m);
$assoc = array_combine($m[1], $m[2]);

You're just looking for a combination of alphanumeric characters \w and optional + signs, then a space, then a \d decimal.

array_combine will give you the associative array.

mario
  • 144,265
  • 20
  • 237
  • 291