问题
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