1

I am looking for a function that suits the following situation.

What the script does: It retrieves the server.log from a minecraft server, and breaks it into sections from user chats, to server notifications etc.

I have an array containing the users information, it is set by another file called users.yml and it is converted to an array like so

$userconfig = array(
    'TruDan'    => array(
        'prefix'    => '&3',
        'suffix'    => '&e',
    ),
    'TruGaming' => array(
        'prefix'    => '&c',
        'suffix'    => '&f',
    ),
    'PancakeMiner'  => array(
        'prefix'    => '&c',
        'suffix'    => '&f',
    ),
    'Teddybear952'  => array(
        'prefix'    => '&b',
        'suffix'    => '&f',
    ),
);

What i want to do, is search the $line from server.log (it loops through lines) for a username above (array key) and return the array. so i can then parse $ret['prefix'] and $ret['suffix']

mc.php (the file) http://pastebin.com/9geyfuup server.log (partial, the actual thing is 12,000 lines long, so i took a few lines from it) http://pastebin.com/DKz8YfgK

4
  • 1
    Sorry, what? Can you explain in more details what is the final out come which you want? Commented Jun 1, 2011 at 20:08
  • thanks for fast reply :) i want it to return the found array for example, if it found "TruDan" it would return the array "TruDan" with the prefix and suffix from that array Commented Jun 1, 2011 at 20:15
  • You want to search for one of these usernames inside the log data, but you haven't given any exemplary log data. If you add that log example data it would be helpful to answer your question. Next to that there are many powerful array functions explained in the PHP manual worth to know about. see php.net/array for the big picture and links to the array functions after the first half of the page. Commented Jun 1, 2011 at 20:36
  • Sorry, i have now put them both on Pastebin. the mc.php and server.log. i added the links into the first post Commented Jun 1, 2011 at 20:40

3 Answers 3

1

If you're using preg_match() to search each line for a username, make sure you first sort the list of usernames in reverse order using rsort():

$users = array_map('preg_quote', array_keys($userconfig));
rsort($users);
$pattern = '/' . implode('|', $users); . '/';
if preg_match($pattern, $line, $matches) {
    return matches[0];
}
else {
    return array();
}

If you search a line for the pattern "/TruDan|TruDan123/" the search will match a line containing "TruDan123" to the shorter version "TruDan" because it was specified first in the pattern. Sorting the user list in reverse order ensures that the pattern will be "/TruDan123|TruDan/" and so give preference to the longer match.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much. this worked perfect. sorry i cannot give you rep as i do not have enough rep :(
0

I'm not sure I 100% understand the question, but based on what I gather you'd like to use the above array (keys) as the needle, and the $line as a haystack?

Could do it in multiple ways, but something such as:

// Regex Method
// this depends on how big this array is though, however, otherwise this
// regex pattern could potentially be HUGE.
$pattern = sprintf('/(%s)/g', implode('|', array_map('preg_quote',array_keys($userconfig))));
if (preg_match($pattern,$line,$matches)){
  // $matches has all names found in the line
  // $userconfig[$match[1]]
}

Otherwise you could keep iterating over the keys:

// "brute fore"
// this keeps checking for $name int he $line over and over, but no real
// optimizations going on here.
foreach (array_keys($userconfig) as $name)
{
  if (strpos($line,$name) !== false)
  {
    // $name was found in $line
    // $userconfig[$name]
  }
}

2 Comments

so far, the log file is nearly 12,000 lines long. but i will soon be making php only show the last 1000 but yes, i would like to search the $line to see if one of the array keys exist, and if it finds one that does. it returns the one its found.
@DanSpiteri: Then you're going to have to play with benchmarking, optimizing, and seeing what works for you. There are (quite possibly) dozens of ways to tackle this. It's just about finding what way works within a time frame that you consider acceptable.
0

So you want to take 'TruDan', 'TruGaming', 'PancakeMiner', and 'Teddybear952' and see if they show up in a particular log file at all?

$names = array_keys($userconfig); // get the user names

$name_regex = implode('|', $names);   // produce a|b|c|d

... load your log file
foreach($lines as $line) {
   if (preg_match("/($names)/", $line, $matches)) { // search for /(a|b|c|d)/ in the string
       echo "found $matches[1] in $line";
       print_r($userconfig[$matches[1]]); // show the user's config data.
   }
}

Of course, this is simplistic. if there's any regex metacharacters in the username, it'll cause a syntax error in the regex, so you'd want to massage the names a bit before building the regex clause.

4 Comments

may want to array_map the $userconfig keys against preg_quote just in case there are special characters (don't know how the data looks, or if we just have a sanitized sample)
pastebin.com/DKz8YfgK there is some part of the server.log you can see in there it has server info, and user chats predator56 (in the log) is also a user the & are colour definers
added the print_r to dump out the user's userconfig data if/when a match is found.
i think this is the one i need, but for some reason. the if statement doesnt get parsed. so nothing gets outputted. pastebin.com/9geyfuup <- this is the php file. at the moment, for debugging, ive put the users info into a flat array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.