1

I have the next array with data (which is dynamically generated). Now I want to do some Magic and tweak the array.

array(1) {
  ["table"]=>
  array(3) {
    ["header"]=>
    array(4) {
      [0]=>
      array(1) {
        ["c"]=>
        string(4) "Naam"
      }
      [1]=>
      array(1) {
        ["c"]=>
        string(7) "Functie"
      }
      [2]=>
      array(1) {
        ["c"]=>
        string(13) "Nevenfuncties"
      }
      [3]=>
      array(1) {
        ["c"]=>
        string(34) " commissies"
      }
    }
    ["caption"]=>
    bool(false)
    ["body"]=>
    array(3) {
      [0]=>
      array(4) {
        [0]=>
        array(1) {
          ["c"]=>
          string(16) "*|class:orange|*"
        }
        [1]=>
        array(1) {
          ["c"]=>
          string(6) "dsasad"
        }
        [2]=>
        array(1) {
          ["c"]=>
          string(0) ""
        }
        [3]=>
        array(1) {
          ["c"]=>
          string(0) ""
        }
      }
      [1]=>
      array(4) {
        [0]=>
        array(1) {
          ["c"]=>
          string(4) "brrr"
        }
        [1]=>
        array(1) {
          ["c"]=>
          string(6) "adsdsa"
        }
        [2]=>
        array(1) {
          ["c"]=>
          string(0) ""
        }
        [3]=>
        array(1) {
          ["c"]=>
          string(0) ""
        }
      }
      [2]=>
      array(4) {
        [0]=>
        array(1) {
          ["c"]=>
          string(6) "dsasad"
        }
        [1]=>
        array(1) {
          ["c"]=>
          string(6) "dsadas"
        }
        [2]=>
        array(1) {
          ["c"]=>
          string(4) "dsad"
        }
        [3]=>
        array(1) {
          ["c"]=>
          string(0) ""
        }
      }
    }
  }
}

When we look at the ['header'] it contains ['c'] (the cell data). This can be text, but also a tag. For example: *|class:orange|* here some text.

Now I want to split those up and overwrite the ['c'] if it contains '|class:orange|'. So when you have this:

   array(1) {
        ["c"]=>
        string(7) "*|class:orange|* hello"
      }

It would become this:

   array(2) {
        ["c"]=>
        string(7) "hello",
        ["class"]=>
        string(7) "orange",
      }

This way I could split the class and add it to the array. But I am stuck at the preg_match.

foreach ($table as &$row) {

    foreach ($row['header'] as &$header) {
//        $header['class'] = 123;

        preg_match('/\*\|class:([^\|])\|\*/', $header['c'], $matches);

    }
}

I need to do 2 things

  • Add an attribute to the array ($header['class']) with the class after class:example.
  • I need to replace the $header['c'] so it does not contain *|class:orange|* and only the rest of the text.
3
  • 1
    The pattern could be like this \*\|class:([^\|]+)\|\*\h*(.+) to get 2 capturing groups regex101.com/r/NvEU5M/1 Commented Mar 20, 2020 at 12:18
  • 1
    Thank you, I have modefy it in \*\|class:([^\|]+)\|\*\h*(.*) so a space is not needed Commented Mar 20, 2020 at 12:46
  • You are welcome, I have added it as an update to the answer. Commented Mar 20, 2020 at 12:53

2 Answers 2

1

No need for regexp (yet). Tags can be found with delimiter positioning:

foreach ($row['header'] as &$header) {
    $str = $header['c'];

    $tagged = substr($str, 0, 2) === '*|' && $pos = strpos($str, '|* ');
    if (!$tagged) { continue; }

    [$tag, $value] = explode(':', substr($str, 2, $pos - 2));
    $header['c']  = substr($str, $pos + 3);
    $header[$tag] = $value;
}
Sign up to request clarification or add additional context in comments.

Comments

1

You could for example use 2 capturing groups and use those as the values for the c and new class key.

For the second capturing group you could make sure to match at least a single non whitespace char using \S

Note to repeat the character class 1 or more times and you don't have to escape the pipe in the character class.

\*\|class:([^|]+)\|\*\h*(\S.*)

Or if what follows for group 2 can be optional:

\*\|class:([^\|]+)\|\*\h*(.*)

Regex demo

Explanation first pattern

  • \*\| Match *|
  • class: Match literally
  • ([^|]+) Capture group 1, match 1+ times any char except |
  • \|\*\h* Match |* followed by 0+ horizontal whitespace chars
  • (\S.*) Capture group 2, match a non whitespace char and 0+ times any char except a newline

Regex demo | Php demo

Example code

$array = [
    "c" => "*|class:orange|* hello"
];

$pattern = "~\*\|class:([^|]+)\|\*\h*(\S.*)~";
foreach ($array as $key => $string) {
    if (preg_match($pattern, $string, $matches)) {
        $array[$key] = $matches[2];
        $array["class"] = $matches[1];
    }
}

print_r($array);

Output

Array
(
    [c] => hello
    [class] => orange
)

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.