Generally, I have a hard time with regex patterns beyond basic matching. I have a simplistic shortcode parser similar to how Wordpress has so an example is:
~PLUGIN::name_of_plugin["param1"="value1","param2"="value2"]~
I have this splitting and working, I just use explode() on the [ and trim the ] to get the parameters portion. Now, I want to pass a nested array so I am trying to do a JSON object into those brackets instead, so the string to parse would look like this:
$str = '~PLUGIN::name_of_plugin[{
"category":"whatever",
"test":[{
"name":"Title Something",
"desc":"123123-A",
"result":"Confirmation",
"conforms":"true",
"mass_spec":"true"
}]
}]~';
After a series of different pattern attempts with varying degrees of success, this is what I came up with that I would consider useable:
preg_match('/^\~([a-z]+::)([a-z\_\-]+)([^\~]+)\~/i',$str,$match);
print_r($match);
It matches to this (I can trim key 3 for what I need):
Array
(
[0] => ~PLUGIN::name_of_plugin[{
"category":"whatever",
"test":[{
"name":"Title Something",
"desc":"123123-A",
"result":"Confirmation",
"conforms":"true",
"mass_spec":"true"
}]
}]~
[1] => PLUGIN::
[2] => name_of_plugin
[3] => [{
"category":"whatever",
"test":[{
"name":"Title Something",
"desc":"123123-A",
"result":"Confirmation",
"conforms":"true",
"mass_spec":"true"
}]
}]
)
The problem there is, if the shortcode doesn't have parameters like:
$str = '~PLUGIN::name_test~';
It splits out to this (notice the n in key 3):
Array
(
[0] => ~PLUGIN::name_of_plugin~
[1] => PLUGIN::
[2] => name_of_plugi
[3] => n
)
Is there some sort of forward-looking thing I should be doing that would make this split out to:
Array
(
[0] => ~PLUGIN::name_of_plugin~
[1] => PLUGIN::
[2] => name_of_plugin
)
but also will split the parameters block out when it exists? I am trying not to do some sort of hack where I implode() key 2 and 3 or something.
It seems that this works by just making the last group optional. I only added ? before the last ~.
Also, ~ and _ are not a special characters, so no need to escape them.
I also added the anchor for end of line $. It's usually a good idea if you want to make sure it captures the whole string.
^~([a-z]+::)([a-z_\-]+)([^~]+)?~$
See it work: regex101
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With