0

I am needing a little help with splitting the contents of a file into a multidimensional array.

Sample of the file contents :

--[DEATH KNIGHT]--
--|Blood|--
--{Single}--
/* MACRO CODE FOR SINGLE TARGET */
--{MULTI}--
/* MACRO CODE FOR MULTIPLE TARGETS */
--|Frost|--
/* MACRO CODE FOR SINGLE TARGET */
--{MULTI}--
/* MACRO CODE FOR MULTIPLE TARGETS */
--{Single}--
--[DRUID]--
--|Guardian|--
--{Single}--
/* MACRO CODE FOR SINGLE TARGET */
--{Multi}--
/* MACRO CODE FOR MULTIPLE TARGETS */

I need to read this file and split it into an array with the following structure :

array(
  'DEATHKNIGHT' => array(
    'Blood' => array(
      'Single' = 'Single Target Macro Code',
      'Multi' = 'Multiple Target Macro Code'
      ),
    'Frost' => array(
      'Single' = 'Single Target Macro Code',
      'Multi' = 'Multiple Target Macro Code'
      )
  ),
  'DRUID' => array(
    'Guardian' => array(
      'Single' = 'Single Target Macro Code',
      'Multi' = 'Multiple Target Macro Code'
      )
)

I am using file_get_contents() to read the contents of the file into a string. I I am using preg_match_all() to pull out my defined array keys. The following are the regex that I am using:

$class_regex = '/(?:-{2})(?:\[)(?:[A-Z][\w]+)(?:[\s][A-Z][\w]+)?(?:\])(?:-{2})/';
$spec_regex = '/(?:-{2})(?:\|)(?:[A-Z][\w]+)(?:[\s][A-Z][\w]+)?(?:\|)(?:-{2})/i';
$target_regex = '/(?:-{2})(?:\{)(?:[A-Z][\w]+)(?:[\s][\(][\d][\D][\)])?(?:\})(?:-{2})/i';

I can pull out the keys successfully, and I can seperate the file into specific elements, but I am struggling when trying to create my array. Any help would be greatly appreciated. Thank you in advance.

3
  • 3
    Read it line by line with while ($line = fgets($file)) instead of reading the whole thing with file_get_contents(). Commented Mar 25, 2016 at 19:02
  • Are those 'target' keys Single and Multi static(constant) within your file content? Commented Mar 25, 2016 at 19:25
  • Yes, 'Single' and 'Multi' are static. everything else is not. The 'Macro Code' will vary in length. Meaning that each 'macro code' will cover a different amount of lines. Commented Mar 25, 2016 at 19:36

1 Answer 1

2

Like Barmar said you should go through it line by line using fgets instead of file_get_contents.

Here is an example script that does what you asked. You'll probably want to extend it with extra validation and such.

<?php
$parsed = array();
$handle = fopen("source.txt", "r");
if ($handle) {
    while (($line = fgets($handle, 4096)) !== false) {
        if (preg_match('/^--\[((?:[A-Z][\w]+)(?:[\s][A-Z][\w]+)?)\]--$/', $line, $match)) {
            $class = $match[1];
        } elseif (preg_match('/^--\|((?:[A-Z][\w]+)(?:[\s][A-Z][\w]+)?)\|--$/', $line, $match)) {
            $spec = $match[1];
        } elseif (preg_match('/^--\{((?:[A-Z][\w]+)(?:[\s][A-Z][\w]+)?)\}--$/', $line, $match)) {
            $target = $match[1];
        } else {
            if (isset($class) && isset($spec) && isset($target)) {
                if (empty($parsed[$class])) {
                    $parsed[$class] = array();
                }
                if (empty($parsed[$class][$spec])) {
                    $parsed[$class][$spec] = array();
                }
                if (empty($parsed[$class][$spec][$target])) {
                    $parsed[$class][$spec][$target] = '';
                }
                $parsed[$class][$spec][$target] .= $line;
            }
        }
    }
    if (!feof($handle)) {
        echo "Error: unexpected fgets() fail\n";
    }
    fclose($handle);
}
echo print_r($parsed);
Sign up to request clarification or add additional context in comments.

Comments

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.