tomtomssi
tomtomssi

Reputation: 1035

Parsing a text file from a certain element name until a different one is found using PHP

The title might be confusing so I will try to be as descriptive as I can with this problem. Here's the text file that is going to be parsed:

server1 2013-08-27 08:42:01

username1   902     1  0 Aug26 ?        00:01:51 Text here

username1  2044     1  0 Jul14 ?        04:54:52 Text here

server2 2013-08-27 08:42:03

username2  2184     1  1 Jul17 ?        10:21:11 Text here

server3 2013-08-27 08:42:05

username3  2225     1  0 Jul17 ?        05:04:25 Text here

server2 2013-08-27 08:42:07

username2 13233     1  0 Jul15 ?        00:15:09 Text here

username2 13233     1  0 Jul15 ?        00:15:09 Text here

server3 2013-08-27 08:42:09

username3  6131     1  0 Jul15 ?        00:22:19 Text here

As you can see, the servers aren't in any specific order. What I would like to acheive is to put the servers and their respective bits of text into arrays. The program would parse the file and whenever it finds "server1" it would put that line and everything below into an array called "server1". When it finds a server with a different name, it would add all the lines of text to another array eg. "server2" or "server3".

The ouput would be something similar to:

//serverX where X is 1-99

array(n){
    [0]=> string(n) "serverX ..."
    [1]=> string(n) "usernameX ..."
    [2]=> string(n) "usernameX ..."
    [3]=> string(n) "usernameX ..."
    [4]=> string(n) "serverX ..."
    [5]=> string(n) "usernameX ..."
}

This means all the servers (server1..n) would have ONE array where strings are added to.

Upvotes: 0

Views: 70

Answers (1)

Alma Do
Alma Do

Reputation: 37365

I suggest to use regex for this. Here's a sample:

//here $sData is incoming plain text data
$rgResult = [];
preg_match_all('/server([^\s]+)\s+([^\r\n]+)(((?!server).)*)/msi', $sData, $rgServers, PREG_SET_ORDER);
foreach($rgServers as $rgMatches)
{
   $rgResult[$rgMatches[1]][] = [
      'date' => $rgMatches[2],
      'list' => array_map(function($sItem)
      {
         return preg_split('/\s+/', $sItem, -1, PREG_SPLIT_NO_EMPTY);
      }, preg_split('/[\r\n]+/', $rgMatches[3], -1, PREG_SPLIT_NO_EMPTY))
   ];
}
//var_dump($rgResult);

I've seen your edit with preferred format, but it's unclear (since somehow your servers are one in another in your sample). Example above will separate servers into array and put each date entry also separately with list of users (assuming user name is also coming first).

Upvotes: 1

Related Questions