Search code examples
phparraystext-search

Getting all array entries that contains certain string, that is next to each other, and the line before the first


I have a PHP array that could look like this:

array(10) {
  [1]=>
  string(69) "2013-06-12 11:25:44 [INFO] There are no objectives on the scoreboard"

  [2]=>
  string(53) "2013-06-12 11:42:27 [INFO] [Server] Hi, how are you?"

  [3]=>
  string(86) "2013-06-12 11:43:40 [INFO] Usage: /scoreboard objectives <list|add|remove|setdisplay>"

  [4]=>
  string(95) "2013-06-12 11:57:51 [INFO] /scoreboard objectives add <name> <criteriaType> [display name ...]"

  [5]=>
  string(67) "2013-06-12 11:57:59 [INFO] Added new objective 'test' successfully"

  [6]=>
  string(64) "2013-06-12 11:58:16 [INFO] Showing 3 objective(s) on scoreboard"

  [7]=>
  string(74) "2013-06-12 11:58:16 [INFO] - test: displays as 'test' and is type 'dummy'"

  [8]=>
  string(89) "2013-06-12 11:58:16 [INFO] - anothertest: displays as 'anothertest' and is type 'dummy'"

  [9]=>
  string(110) "2013-06-12 11:58:16 [INFO] - yetanothertest: displays as 'yetanothertestwithanothername' and is type 'dummy'"

  [10]=>
  string(60) "2013-06-12 11:58:17 [INFO] [Server] Dude, stop doing that!"
}

I'd like to grab items six through nine, and then put them into a new array.

To do this, we would need to do this: Note that I use stars where there can be any content, as long as it has the same charcount as the stars. I use hashtags where there can be any input, not depending on the charcount.

  1. Find the last entry in the array with this syntax: "****-**-** **:**:** [INFO] Showing # objective(s) on scoreboard"
  2. Take all directly following entries with this syntax: "****-**-** **:**:** [INFO] - #: displays as '#' and is type '#'"
  3. Put them into an array

I'm really grounded on this one. I'm pretty sure Regular Expressions would come in handy, but I never managed to understand them.

Thanks in advance

**EDIT: **I completely forgot something very important. Please read this comment.


Solution

  • This is a modified version of raina77ow's code. It wasmissing some checks (read the comment I wrote)

    $datePattern = '\d{4}-\d{2}-\d{2}';
        $timePattern = '\d{2}:\d{2}:\d{2}';
        $headerPattern = $datePattern . ' ' . $timePattern . ' \[INFO] ';
        $showingPattern = $headerPattern 
            . 'Showing \d+ objective\(s\) on scoreboard';
        $messagePattern = $headerPattern 
            . "- [^:]+: displays as '[^']*' and is type '[^']*'";
        $noPattern = $headerPattern
            . "There are no objectives on the scoreboard";
    
        $results = array();
    
        $i = $max = count($arr);
        while ($i--) {
          $msg = $arr[$i];
          if (preg_match("/^$showingPattern/", $msg)) {
            $result = array($msg);
            for ($j = $i + 1; $j < $max; $j++) {
              $nextMsg = $arr[$j];
              if (preg_match("/^$messagePattern/", $nextMsg)) {
                $result[] = $nextMsg;
              }
              else {
                break;
              }
            }
            $results[$i] = $result;
          }
        }
    
        $no=preg_grep("/^$noPattern/",array_reverse($arr));
    
        $results=array_shift($results);
        $count=count($results);
    
        $notime=strtotime("the 1st of september 1971");
        $notime=strtotime(substr(array_shift($no),0,19));
        $resulttime=strtotime(substr($results[0],0,19));
    
        if ($resulttime>$notime) {
            for($i=0;$i<$count;$i++){
                echo substr($results[$i],27).'<br/>';
            }
        }
        else echo 'There are no objectives on the scoreboard';