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

StackOverflow https://stackoverflow.com/questions/17062977

  •  31-05-2022
  •  | 
  •  

Pregunta

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.

¿Fue útil?

Solución 2

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';

Otros consejos

Here's one possible approach:

  • create two patterns, one for the 'Showing...' message and other for 'Displaying' message;
  • iterate over your array in a reverse order (from the end to the beginning), checking each string
  • if the string matches 'Showing pattern', check each consequent string for 'Displaying' pattern match; if it does, place it into some container. The matched string should be probably placed into this container too.

And here's one possible implementation:

$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 '[^']*'";

$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;
  }
}
var_dump($results);

Demo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top