Replace data in array based on regex

落爺英雄遲暮 提交于 2020-03-23 07:57:10

问题


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.

回答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;
}



回答2:


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
)


来源:https://stackoverflow.com/questions/60773924/replace-data-in-array-based-on-regex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!