I’m working on a type of page builder with Laravel and try to implement shortcodes WordPress style. I have HTML code as a string like this:
$string = '<div class="temp">
[title type="text" tag="h2" value="This is my cool title" disabled some-attribute]
[text type="text" tag="p" value="Lorem ipsum dolor sit amet"]
</div>';
Ok, now I want to extract and store all the "shortcodes" (the stuff in the brackets […]) in an array like this:
[
[
"id" => "title",
"type" => "text",
"tag" => "h2",
"value" => "This is my cool title",
"disabled" => true,
"some-attribute" => true
],
[
"id" => "text",
"type" => "text",
"tag" => "p",
"value" => "Lorem ipsum dolor sit amet"
]
]
My problem is to explode the shortcode strings to an array because of the spaces in "".
Here is my PHP code:
// Extract all brackets from the string
preg_match_all('/(?<=[)[^][]*(?=])/', $string, $matches);
$itemsArray = array();
// Explode each shortcode by spaces
foreach ($matches[0] as $match) {
$shortcode = explode( ' ', $match );
$itemArray = array();
// split shortcode in attributes
foreach ($shortcode as $key => $attr) {
$temp = explode('=', $attr);
// First attribute is the id
if ($key === 0) {
$itemArray['id'] = $temp[0];
} else {
if ( count($temp) > 1 ) {
$itemArray[ $temp[0] ] = trim($temp[1],'"');
} else {
$itemArray[ $temp[0] ] = true;
}
}
}
$itemsArray[] = $itemArray;
}
The result is close but the spaces in the quotes "" screw up the explode of the strings:
[
[
"id" => "title"
"type" => "text"
"tag" => "h2"
"value" => "This"
"is" => true
"my" => true
"cool" => true
"title"" => true
"disabled" => true
"some-attribute" => true
],
[
"id" => "text"
"type" => "text"
"tag" => "p"
"value" => "Lorem"
"ipsum" => true
"dolor" => true
"sit" => true
"amet"" => true
]
]
How can I exclude the spaces in the string explode?
4
Answers
Maybe this will work for you? Pls let me know
Due to the value attributes also containing spaces, the result is not expected. Instead of exploding by spaces, you need to apply a second regex:
If you look at your string, other than the items inside the DIV starting with a [ and ending with ] they’re pretty much the same as a standard HTML DOM element anyway so it might be easier to convert those lines to HTML and then access it all via the DOMDocument.
Try this quick example
If you know the values will never contain square brackets you could try getting that data this way via PHP’s DOMDocument feature.
It might need tweaking.
Like I said, the capturing of the elements via [ and ] might need a stricter way of achieving that to avoid any nasty surprises when a value contains a "]" inside it.
I hope this helps a little for ideas.
You can make use of the PHP internal tokenizer.
Demo: https://3v4l.org/1ThIF
$tag
withid
key.$tag
list as key and atrue
value.$key
and$value
.$tag
list with key and trim the quotes off the value.$tag
list trim the quotes off the previous and tokenized value concatenated with a space.$tag
to the$result
.