The result and the end of moves for the last game gets replaced with '~', like all the others. This means after the explode, there's an empty string after all the game data (try explode('~', 'a~b~')). When you call preg_match_all('/\[(\w+) "([^"]+)"\]/', $game, $matches, PREG_SET_ORDER); on an...